iOSのカメラというかAVFoundationにはAdobeのLightroomアプリのようにホワイトバランスやシャッタースピードなどをカスタマイズするAPIがあります。
ドキュメントを読んでみて難しい部分があったので整理しておこうと思います。
Lightroom
LightroomのiPhone版では撮影時に微調整しながら撮影できます。
↑の矢印部分をタップしてプロに切り替える(元々はAuto)と、シャッタースピードやISO感度、ホワイトバランスを調整するコントロールが現れます。ここで色々いじると設定を変えられるわけですね。
iOSでの実装
ベース部分
AVFoundation
のAVCapturePhotoOutput
を使います。よくあるコードなので特に解説しませんが、こんな感じになりますよね。
deviceの設定をするconfigureDevice
というfunctionが最後にあります。今はオートフォーカスを有効にすることしかしていませんが、ここで色々設定を変更していきます。
import UIKit
import AVFoundation
class CameraViewController: AppViewController {
let captureSession = AVCaptureSession()
var photoOutput : AVCapturePhotoOutput!
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
override func viewWillAppear(_ animated: Bool) {
captureSession.startRunning()
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
captureSession.stopRunning()
super.viewWillDisappear(animated)
}
private func getDevice() -> AVCaptureDevice? {
let discoverSession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInTelephotoCamera, .builtInWideAngleCamera], mediaType: .video, position: .back)
return discoverSession.devices.first
}
private func configure() {
if let device = getDevice() {
do {
try device.lockForConfiguration()
self.configureDevice(device: device)
device.unlockForConfiguration()
} catch { print("error") }
do {
let input = try AVCaptureDeviceInput(device: device)
captureSession.addInput(input)
} catch { print("error") }
photoOutput = AVCapturePhotoOutput()
if captureSession.canAddOutput(photoOutput) {
captureSession.addOutput(photoOutput)
let captureVideoLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.init(session: captureSession)
captureVideoLayer.frame = self.imageView.bounds
captureVideoLayer.videoGravity = .resizeAspectFill
self.imageView.layer.addSublayer(captureVideoLayer)
}
}
}
func configureDevice(device: AVCaptureDevice) {
if device.isFocusModeSupported(.continuousAutoFocus) {
device.focusMode = .continuousAutoFocus
}
// その他設定
}
}
シャッタースピードとISO
AVCaptureDevice
のsetExposureModeCustom
を使います。
先程のconfigureDevice
に追記するとして、たとえばシャッタースピードを1/400、ISOを800にするのであれば↓のように設定できます。
let shutterSpeed = CMTimeMake(1, 400)
device.setExposureModeCustom(duration: shutterSpeed, iso: 800, completionHandler: nil)
ホワイトバランス
ホワイトバランスのほうは少々厄介でして、iOS側のAPIはWhiteBlanceGains
というstructを使用します。
Lightroomのアプリにおけるホワイトバランスの設定は「蛍光灯」や「昼光」など、色温度ベースとなっています。そこで色温度などからWhiteBalanceGains
に変換する必要があります。
let k = 6000 // 色温度
let tint = -5 // -150.0〜+ 150.0の範囲のホワイトバランスの色合い値
let values = AVCaptureDevice.WhiteBalanceTemperatureAndTintValues(temperature: k, tint: tint)
let gains = device.deviceWhiteBalanceGains(for: values)
device.setWhiteBalanceModeLocked(with: gains, completionHandler: nil)
まず、AVCaptureDevice.WhiteBalanceTemperatureAndTintValues
を色温度と色合いの値を使って初期化し、それを元にWhiteBalanceGainsにします。次にsetWhiteBalanceModeLocked
によりホワイトバランスを設定します。
こちらは色温度だけでなくtintValueの影響もあるので欲しい設定にするには微調整が必要そう。
ともかくこれでよくやりそうな設定は変更できました。