LoginSignup
11
12

More than 5 years have passed since last update.

Photo Editing Extensionメモ&サンプル

Posted at

Photo Editing ExtensionはiOS標準の「写真」アプリから呼び出せる、画像編集機能を提供するエクステンションです。

photo_editing_extension.jpg

写真にVignette効果を適用するサンプルを作成しました。
https://github.com/imk2o/Try-AppExtensions

処理の流れ

  • ビューコントローラがインスタンス化される
  • 以前の補正データに対応しているか返答する
    • PHContentEditingController#canHandleAdjustmentData(_:)
  • 編集開始の準備をする
    • PHContentEditingController#startContentEditingWithInput(_ contentEditingInput: PHContentEditingInput!, placeholderImage placeholderImage: UIImage!)
  • 編集を完了する
    • PHContentEditingController#finishContentEditingWithCompletionHandler(_:)
    • PHContentEditingController#cancelContentEditing()

canHandleAdjustmentData(_:)

以前の補正データが読み込めるのであればtrueを返します。バージョンや補正データの内容から判断することになるはず。

    func canHandleAdjustmentData(adjustmentData: PHAdjustmentData?) -> Bool {
        guard let adjustmentData = adjustmentData else {
            return false
        }

        // IDとバージョンが一致しているか?
        return adjustmentData.formatIdentifier == self.formatIdentifier && adjustmentData.formatVersion == self.formatVersion
    }

startContentEditingWithInput(_ contentEditingInput: PHContentEditingInput!, placeholderImage placeholderImage: UIImage!)

引数contentEditingInputは完了時に必要なので握っておきます。
placeholderImageは、プレビュー表示用のイメージが完成するまでの一時的な表示に利用できます。
(前回の編集が適用された画像のため、プレビュー用の入力画像には使用しないほうがいいです)

    func startContentEditingWithInput(contentEditingInput: PHContentEditingInput?, placeholderImage: UIImage) {
        self.input = contentEditingInput

        // 前回編集時の設定したパラメータを取得し、スライダーに反映
        let parameters = NSKeyedUnarchiver.unarchiveObjectWithData(self.input.adjustmentData.data) as? [String: AnyObject]
        if let inputIntensity = parameters?["inputIntensity"] as? Float {
            self.slider.value = inputIntensity
        }

        // プレビュー用の入力CI画像を生成しておく
        if let CGImage = self.input.displaySizeImage?.CGImage {
            self.ciInputImage = CIImage(CGImage: CGImage)
        }

        self.updatePreview()
    }

finishContentEditingWithCompletionHandler(_:)

テンプレートどおり、バックグラウンドで最終画像の出力を行います。
input.fullSizeImageURLからオリジナル画像を取得し、編集を適用した画像ファイルを
output.renderedContentURLに出力します。

output.adjustmentDataに補正データを出力しておけば、ユーザが再度編集を行う際にパラメータを復元できます。nilにはできませんが、空のNSDataを渡してもエクステンションは機能します。

    func finishContentEditingWithCompletionHandler(completionHandler: ((PHContentEditingOutput!) -> Void)!) {
        // Render and provide output on a background queue.
        dispatch_async(dispatch_get_global_queue(CLong(DISPATCH_QUEUE_PRIORITY_DEFAULT), 0)) {

            let output = PHContentEditingOutput(contentEditingInput: self.input)
            let inputIntensity = self.currentValue

            // 編集パラメータを構築
            output.adjustmentData = PHAdjustmentData(
                formatIdentifier: self.formatIdentifier,
                formatVersion: self.formatVersion,
                data: NSKeyedArchiver.archivedDataWithRootObject(["inputIntensity": inputIntensity])
            )

            // オリジナル画像を取得し、フィルタを適用
            guard
                let inputImageURL = self.input.fullSizeImageURL,
                let ciInputImage = CIImage(contentsOfURL: inputImageURL)
            else {
                return  // FIXME
            }
            let filteredImage = ciInputImage.createVignetteFilteredImage(inputIntensity, context: self.ciContext)

            // JPEGファイルを出力 (TODO: CIImageから直接JPEGファイルを出力する方法はあるのか?)
            guard let JPEGData = UIImageJPEGRepresentation(filteredImage, 0.8) else {
                return  // FIXME
            }
            JPEGData.writeToURL(output.renderedContentURL, atomically: true)

            // Call completion handler to commit edit to Photos.
            completionHandler?(output)
        }
    }

メモ

写真に編集を適用すると、オリジナル画像はオモテに表示されなくなります。
データ自体は残っており、ユーザが「元に戻す」を行うことでオリジナル画像が復元されます。

参考

11
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
12