[SwiftUI][Image] イメージ処理アプリを作る(6)

SwiftUI

SwiftUI を使った イメージ処理アプリを作ってみます

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.1
  • Xcode 12.3

本シリーズ内容

SwiftUI を使って、イメージ処理するアプリを作ります。

以下の理解が進むことがゴールです。

  • SwiftUI を使ったアプリ開発
  • NSImage を使った画像処理全般
  • Photos 拡張編集機能 と SwiftUI app の組み合わせ方
  • イメージ処理アプリも TDD で進めることが可能かどうか
  • その他 macOS app 開発 Tips

この記事で作る範囲

Photos (写真) アプリの編集拡張機能として作るための環境を説明します。

  • ターゲット「Photo Editing Extension」
  • PhotoEditingViewController
  • PHContentEditingInput
  • PHContentEditingOutput

Photos 編集拡張機能の作成手順

Photos は、編集機能を外部アプリを使って行うことができるようになっています。Affinity Photo 等もこの仕組みを使って、Photos からの編集をサポートしています。

この仕組みを使って、メガネをつけるような編集機能を Photos に追加していきます。

以下のような流れになります。

  1. 編集機能作成
  2. Photo Editing Extension ターゲット追加
  3. PhotoEditingViewController を使って、編集 UI の設定
  4. PhotoContentEditingInput から編集対象の取得
  5. PhotoContentEditingOutput 経由で、編集したデータを渡す

Photo Editing Extesion 作成

ターゲット追加

既存プロジェクトのターゲットを追加します。Wizard で表示される “Photo Editing Extension” を選択して進めていきます。

  1. ターゲット追加ボタンを押下します
    ターゲット追加ボタン
    ターゲット追加ボタン
  2. ”Photo Editing Extension”を選択します
    ”Photo Editing Extension
    ”Photo Editing Extension”選択
  3. Product Name を指定します
    ProductName指定
    ProductName指定
  4. Photo Extension 向けの Scheme を Active にするか聞かれますので、”Activate” を選択します
    SchemeActivate
    SchemeActivate
  5. (うまく作成できたか確認するために一度起動してみます。) ⌘ + R で実行します。
  6. どのアプリケーション上で動作させるか聞かれますので、Photos を選択します
    LaunchWithPhotos
    LaunchWithPhotos
  7. Photos 内で、画像を編集モードにし、機能拡張メニューのプルダウンから 作成している Extension を選択し起動します
    機能拡張選択
    機能拡張選択
  8. 何も実装していませんので、真っ黒な画面が表示されますが、それで OK です。(編集モードを抜けるときには、キャンセルを押下します)
    起動画面
    起動画面

ターゲット追加できたことを確認しましたので、関連するクラスを確認します。

PhotoEditingViewController/PHContentEditingController

“Photo Editing Extension” を選択すると作成されるテンプレートクラスです
NSViewController と PHContentEditingController を継承しています。
Photos の機能拡張として使用される ViewController です。Photos の機能拡張としては、PHContentEditingController プロトコルがポイントになります。

Apple のドキュメントは、こちら

canHandle

直近の編集について、継続して編集することができるかを返すことのできるメソッドです。

独自データ保存のために、PHAdjustmentData というデータを Photos 側に保持させることができるのですが、直近の編集で保存された PHAdjustmentData が渡されてくるので、それを使うことで、継続編集可能かどうかを返します。

true を返すと イメージ情報は、編集前のオリジナルのものが渡されてきます

startContentEditing

編集操作を選択されるとよばれます。この後に、自分の ViewController で UI が表示されることになります。

finishContentEditing

Photos の “変更内容を保存” ボタンを押下されると呼び出されます。

編集データを渡した後に、completionHandler を呼び出しますが、中間データ削除等のクリーンアップは、completionHandler 呼び出し後に行います。

shouldShowCancelConfirmation

キャンセル時に、”変更を破棄”してよいかの確認ダイアログを出すかどうかを制御します。

例えば、ユーザーがすでに編集操作をしていた場合には、確認ダイアログを出す方が一般的です。

cancelContentEditing

Photos の “キャンセル”ボタンを押下されると呼び出されます。

キャンセル操作なので、編集したデータを渡す必要はなく、中間データの削除等 必要なクリーンアップ作業を行うタイミングになります。

PhotoContentEditingInput

PHContentEditingController#startContentEditing で渡されてくるクラスです。このクラスを経由して、Photos から編集対象のデータを受け取ります。

Apple のドキュメントは、こちら

写真を対象としたときの主要なプロパティのみ説明します。

adjustmentData

canHandle で true と返していると継続編集できるということですので、PHAdjustmentData が付与されてきます。(image には、編集前のデータが入ってきます)

displaySizeImage

表示用のイメージが渡されます。

fullSizeImageURL

実データが必要であれば、この URL から取得します。

PhotoContentEditingOutput

PHContentEditingController#finishContentEditing で渡されてくるクラスです。このクラスを経由して、Photos に編集したデータを渡します。

Apple のドキュメントは、こちら

adjustmentData:PHAdjustmentData?

自 Extension のデータ保存用のクラスです。必要に応じて、自 Extension のためのデータを保存します。
ただし、画像等の巨大データを保存することはできません。

renderedContentURL:URL

編集後のデータを出力する URL です。adjustmentData も渡していますが、このデータには 必要な変更が 組み込まれている必要があります。

Photo Editing Extension ターゲットを作った後にすること

確認できたように、テンプレートを生成するだけで、Photos から 機能拡張の1つとして、認識されるものが出来上がります。

機能拡張を動作するものにするためには、以下の作業が必要となります。

  • 編集 UI の表示
  • 編集機能実装
  • 保存処理の実装
  • キャンセル処理の実装

この記事でできたこと

  • Photos から機能拡張として呼び出すことのできるテンプレートコードの生成
  • Photos の編集機能拡張で使用されるクラスの理解

次回

次回以降で、ここまでに作成してきた機能を、Photos の編集機能拡張として動くようにしていきます。

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です