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

SwiftUI

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

環境&対象

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

  • macOS Big Sur 11.1
  • Xcode 12.3
  • Photos 6.0

本シリーズ内容

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

以下の理解が進むことが目標です。

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

この記事で作る範囲

Photos の編集機能拡張として、写真を編集して Photos に保存できるようにしていきます

  • 編集用 UI を表示する
  • Photos から渡される写真を UI に表示する
  • 編集した 写真を Photos に渡す

準備

アプリとして作成してきた UI を Photos からも利用する予定です。

アプリとして作成していたときには、編集したデータを保存するボタンをつけていましたが、Photos の中の UI として、独自に保存ボタンを持つのは不自然なので、ビューを階層化して、編集ビューに直接ボタンを配置することをやめます

以下のように、ビューを2階層にして、MainView を Photos から利用できるビューにします。

これまでの実装(MainView)

現在の MainView を2つに分けて、編集用のビューと Save ボタンを別々のビューとします。

また、Photos 内で、Drag&Drop を受け付けるのも良くないので、onDrop 処理も、MainView から外します。

MainView と MainViewWithSave

この変更によって、Photos から MainView を再利用しやすくなりました。

編集用 UI を表示する

やること

アプリとして、SwiftUI で UI を作っているので、その UI を Photos にも表示します。

テンプレートとして生成されている PhotoEditingViewController に実装を追加していきます。

実装/ viewDidLoad

Photos は、NSView/NSViewController を期待しているので、
SwiftUI の View を NSHostingView でラップして渡します。

まずは、viewDidLoad に追加していきます。

PhotoEditingViewController#viewDidLoad

glassHostView の frame は適当に決めています。

上記で、Photos から外部編集機能拡張として起動すると UI が表示されるようになります。

Photos から渡される写真を受け取る

やること

編集開始時に、startContentEditing がよばれるので、Photos から写真を受け取り、自 UI に表示するようにします。

Photos からは、表示用のデータと 実データのどちらも PHContentEditingInput から取得できるようになっています。

今回のアプリでは、常に実データを扱うようにしていましたので、表示用のデータは無視して、実データを 自アプリに保持するようにします。

実装/ startContentEditing

PhotoEditingViewController#startContentEditing

Photos へ編集した写真を渡す

やること

Photos 上で、”変更内容を保存”ボタンを押下されると finishContentEditing が呼ばれます。

PHContentEditingOutput から指定される URL に編集後のデータを書き出し、CompletionHandler をコールします。

なお、AdjustmentData として何らかを保存しないと、書き出したデータは無視されてしまう仕様のようです。ここでは、ダミーを入れています。

実装/ finishContentEditing

PhotoEditingViewController#finishContentEditing

作成した編集機能拡張の動作

ここまでの実装で以下のような動作になります。

この記事でできたこと

  • SwiftUI で作ったアプリを Photos の編集機能拡張として使えるようにした

まとめ:イメージ処理アプリと Photos 編集機能拡張

  • NSImage を使って、イメージを扱うのは、UIKit/AppKit と同じ
  • SwiftUI で作った UI は、NSHostingView を使うことで、Photos 編集機能拡張としても使える
  • 写真を扱うには、NSImage だけでは不十分で CoreImage を使う必要がある
  • 編集内容そのものを TDD でテストしていくのは難しそう

作成したアプリ/編集機能拡張 では以下のような点が 改善・拡張 の対象と考えられます

  • UI の表示領域を可変にする(ドラッグで拡大縮小可能にする)
  • Photos の表示領域いっぱいに、編集用 UI を表示する
  • Photos 上での再編集に対応する

最初の2つは、canvasSize として保持している変数を使うと対応することができ、3つ目は、EditModel に保持している変数を serialize して adjustmentData にすることで対応可能です。

一段落したので、本アプリ開発の記事は、一旦終了とします。

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

コメントを残す

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