[iOS 10] RAW形式の写真を撮影する方法

2016.09.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

RAWイメージのサポート

こんにちは!
モバイルアプリサービス部の田中孝明です。

iOS 10以降ではA8/A9以降のCPUを搭載した端末でのRAWイメージのサポートがされるようになりました。
これにより、撮影する写真を圧縮せずに、アプリ側、もしくはユーザーが3rdパーティのアプリを利用して任意の加工ができるようになりました。

AVCapturePhotoSettingsの設定

AVFoundationAVCapturePhotoOutputから有効なRAWイメージの種類を取得します。
AVCaptureSessionAVCapturePhotoOutputの利用方法についてはこちらに使用方法を記載していますので、よろしければ参照してください。

stillImageOutput?.availableRawPhotoPixelFormatTypes


AVCapturePhotoSettingsに有効なRAWイメージの種類を指定します。

let settingsForMonitoring = AVCapturePhotoSettings(rawPixelFormatType: 1919379252)
settingsForMonitoring.flashMode = .auto
settingsForMonitoring.isHighResolutionPhotoEnabled = false


RAWイメージの撮影

AVCapturePhotoOutputcapturePhoto(with settings: AVCapturePhotoSettings, delegate: AVCapturePhotoCaptureDelegate)にAVCapturePhotoSettingsの設定を追加し、デリゲートを指定することで撮影後のRAWイメージの取得ができます。

stillImageOutput?.capturePhoto(with: settingsForMonitoring, delegate: self)


RAWイメージ取得完了後は以下のデリゲートメソッドが呼ばれます。

capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingRawPhotoSampleBuffer rawSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?)


このデリゲートメソッドの内部で写真の取得処理を行います。
rawSampleBufferに格納されたバッファからAVCapturePhotoOutputの以下のメソッドを使用してDataに変換します。

dngPhotoDataRepresentation(forRawSampleBuffer rawSampleBuffer: CMSampleBuffer, previewPhotoSampleBuffer: CMSampleBuffer?) -> Data?


今回は一時的にtmp直下に置いていますが、必要に応じてPhotoライブラリに置くことも可能です。

extension ViewController: AVCapturePhotoCaptureDelegate {

    func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingRawPhotoSampleBuffer rawSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
        if let error = error {
            print(error.localizedDescription)
        }

        if let _rawSampleBuffer = rawSampleBuffer {
            let director = NSTemporaryDirectory()
            let filename = String(format: "%lld.dng", resolvedSettings.uniqueID)
            let temporaryURL = NSURL(fileURLWithPath: director).appendingPathComponent(filename)

            let imageData = AVCapturePhotoOutput.dngPhotoDataRepresentation(forRawSampleBuffer: _rawSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)

            try! imageData?.write(to: temporaryURL!)
        }
    }
}


RAWイメージ

tmp直下に置かれたデータです。
拡張子はDNG、ファイルの種類はAdobe raw imageとなっています。
スクリーンショット 2016-09-04 22.29.30

まとめ

iPhone 6s / iPhone 6s Plus / iPad Pro 9.7は1200万画素のカメラを搭載していることもあり、RAWデータを利用して写真を自分好みに加工したいニーズも出てくるかもしれません。
また、CoreImage.frameworkにもRAWイメージを編集する機能が追加されていますので、そちらも併せて試してみるのもいいかもしれません。

参考文献

AVCapturePhotoOutput - Beyond the Basics
AVCapturePhotoOutput
AVCapturePhotoSettings