AVFoundationを用いたカメラの実装
iOSではデフォルトのカメラをそのまま出すこともできますが、AVFoundationを使えばカメラを自由にデザインすることができます。
主なオブジェクトの説明
- AVCaptureSession
下記に説明するAVCaptureInputとAVCaptureOutputを追加し、キャプチャのアクティビティ全体を管理するものです。キャプチャの開始・停止やアウトプットの質を指定することができます。 - AVCaptureInput
インプット形式を指定する抽象クラスですが、基本的にはこれのサブクラスであるAVCaptureDeviceInput
を使うと思います。カメラやマイクなどキャプチャを行うデバイスをAVCaptureSessionを追加するためのものです。 - AVCaptureOutput
アウトプット形式を指定する抽象クラスです。静止画や動画ファイル、音声ファイルなどがサブクラスとして用意されています。それぞれ出力を行うメソッドを持っています。
0. AVFoundationのインポート
1. 使用するオブジェクトの宣言
今回はカメラからの入力映像をプレビューし、静止画のキャプチャを行うので、AVCaptureSessionとAVCaptureOutput, キャプチャ時の設定を指定するAVCapturePhotoSettings, それからプレビュー画像を表示するAVCaptureVideoPreviewLayerをプロパティとして宣言します。
2. カメラの設定
インプットを行うデバイスを取得し、AVCaptureDeviceInputを生成した後、AVCaptureSessionに格納します。session.startRunning()
でインプットが開始されます。
また、アウトプット前のプレビュー表示もここで設定します。videoGravity
には、指定した範囲内にカメラから得られた映像をどのように表示するかを指定します。
さらに、先ほど宣言したAVCapturePhotoSettingsに対し、静止画キャプチャを行う際の設定を指定しましょう。フラッシュの有無以外にも、手ぶれ補正や最高解像度で撮影するか否かなどを指定できます。
3. キャプチャ処理の呼び出し
キャプチャボタンを押した時に画像を書き出す処理を記述します。AVCapturePhotoOutputのcapturePhoto(with: delegate:)
にキャプチャ時の設定と出力を担うdelegateを指定します。
4. デリゲートメソッドの記述
AVCapturePhotoCaptureDelegateを継承しましょう。この中のphotoOutput(_: didFinishProcessingPhoto: error:)
でキャプチャされた画像を受け取ります。引数はAVCapturePhotoで渡されるので、ここからfileDataRepresentationメソッドでData型の画像ファイルを生成できます。
5. 出力画像の切り取り
しかしながら、上記の実装ではプレビューと異なるサイズの画像が取得されます。これはvideoGravity
で指定したように、カメラからの映像をスケールしてプレビューに表示しているからです。画像を切り抜いてプレビュー通りのサイズにしましょう。
まず、出力された画像サイズを取得します。imageOrientationが横向きに回転してしまっている時もあるので、その場合は高さと幅を逆にしてCGSizeを生成します。
次に、previewLayerのrectを切り抜きたいviewの座標系に変換し、これらを用いて切り抜く範囲を計算します。.integral
では、CGRectの小数点の値をそれと同等な整数に変換しています。
このrectを用いてcropしてあげれば完了です。
以上でAVFoundationを用いたカメラの説明を終わります。特に、切り抜く部分のドキュメントがあまりないので、この記事を参考にしていただければ嬉しいです。
参考文献