【Swift】カメラのズーム倍率をアニメーションさせながら操作する
概要
カメラアプリを作る際、AVFoundation
フレームワークを利用します。
弊社が開発しているカメラアプリNow Cameraで、AVCaptureDevice
のズーム機能周りをリファクタする実装に関わったので、備忘録としてまとめました。
ズームの基本
キャプチャーセッションの初期化やinputDevice周りの設定を終えた状態で、AVCaptureDevice.videoZoomFactor: CGFloat
に倍率を代入します。
実装
let device: AVCaptureDevice = ...
try device.lockForConfiguration()
device.videoZoomFactor = 4.0 // 👈 ズームさせたい倍率を指定
device.unlockForConfiguration()
ズームをアニメーションさせる
videoZoomFactor
に直接値を代入すると、パッと一瞬で倍率が切り替わります。アニメーションさせたい場合は代わりにAVCaptureDevice.ramp(toVideoZoomFactor:withRate:)
メソッドでアニメーションさせることができます。
toVideoZoomFactor
目標のズーム倍率を、rate
はズーム倍率の変化率を指定します。[2]
let device: AVCaptureDevice = ...
let factor: CGFloat = ...
try device.lockForConfiguration()
device.ramp(toVideoZoomFactor: factor, withRate: 2.0) // 👈 アニメーションさせながらズーム倍率を変化させる
device.unlockForConfiguration()
ズームアニメーションをキャンセルする
ramp
のアニメーションを途中でキャンセルすることもできるようです。AVCaptureDevice.cancelVideoZoomRamp()
でキャンセルできます。
let device: AVCaptureDevice = ...
if device.isRampingVideoZoom {
try device.lockForConfiguration()
device.cancelVideoZoomRamp() // 👈 ズームアニメーションをキャンセルする
device.unlockForConfiguration()
}
AVCaptureDeviceのズーム倍率の最小値、最大値を取得する
videoZoomFactor
に指定できる値の最小値と最大値は、minAvailableVideoZoomFactor: CGFloat
とminAvailableVideoZoomFactor: CGFloat
に格納されています。
ズーム倍率をUIに表示する
超広角カメラが搭載されているデバイス等で純正カメラアプリを起動すると、ズーム倍率の最小値が0.5と表示されることがあります。しかし、AVCaptureDevice
のvideoZoomFactor
の最小値は1.0です。
どちらも同じズーム倍率を指しているのですが、AVCaptureDevice.displayVideoZoomFactorMultiplier: CGFloat
の係数を利用することでUI上いい感じにできます。
ただし、iOS 18.0以降でのみ利用可能なAPIなのでそれ以前のOSでのフォールバックも考慮する必要があります。😢
let device: AVCaptureDevice = ...
let currentZoomFactor: CGFloat = ...
@available(iOS 18.0, *)
var displayingZoomFactor: CGFloat {
currentZoomFactor * device.displayVideoZoomFactorMultiplier // 👈 倍率をUI上でいい感じにする
}
// Camera View
Text("ズーム倍率は \(displayingZoomFactor) です。")
関連
Discussion