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

SwiftUI

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

環境&対象

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

  • macOS Big Sur 11.1
  • Xcode 12.3

本シリーズ内容

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

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

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

完成イメージ

写真に、メガネのイメージを重ねた写真を作るアプリにしてみます。

以下のような見た目になるイメージ

完成イメージ
完成イメージ

この記事で作る範囲

まずは、以下の実装をしていきます。

  • 写真を表示する
  • 写真に重ねて、眼鏡を表示する
  • 眼鏡をドラッグできるようにする (-> 次回以降に)

写真を表示する

やること

将来的には、Drag&Drop できるようにしたいですが、まずは、リソースとして保持している写真を表示することにします。

テスト

この状態では、モデルもビューモデルもないので、シンプルに、「起動直後に表示されているイメージの名前が適切か」をテストすることにします。

テストコードとしては、以下のようになるはずです。

test_appLaunch_initial_imageShouldBeInitialImage

コード解説
  1. ID: mainImage を持つイメージを取得
  2. イメージが表示しているものが initialPhoto であることをテスト

まだ、アプリのコードは書いていないので、当然エラーとなります。(mainImage というイメージが取得できないというエラーになるはずです)

アプリ実装

イメージの表示は、SwiftUI では、Image を使います。初期イメージは、適当(?)なイメージをリソース(Assets.xcassets)に、”initialPhoto” という名前で追加します。

ContentView
コード解説
  1. 今後、別の写真も表示する予定なので、@State で NSImage を保持するようにします。
  2. 写真を表示するために、Image を使っています。フレームの大きさは適当に決めました。
  3. テストで取得できるように AccessibilityID を付与しておきます。

こうすることで、先ほどのテストをパスすることができるようになりました。

写真を表示しているアプリ
写真を表示しているアプリ

メガネの表示

やること

先ほどの写真に重ねて表示するので、ZStack を使います。

メガネの表示は、先ほどの写真と同じです。リソースに追加しておいて、Image を使って表示します。

テスト

写真とメガネの両方が表示されていることをテストします。

起動時のチェックなので、先ほどのテストを拡張します。

test_appLaunch_initial_imageShouldBeInitialImage

コード解説
  1. 写真と同じように、ID: glass を持つイメージを取得
  2. イメージが “glass” を表示していることをテスト

アプリ実装

initialPhoto と同様に、メガネ用のイメージをリソースに追加して表示します。

ZStack を使って initialPhoto に重ねて表示するようにします。

なお、メガネのイメージは、背景を透明にした png ファイルを用意しました。

ContentView

コード解説
  1. 重ねて表示するので ZStack を使います
  2. glass という名前でリソースに保存したイメージを表示します
  3. glass という ID を付与します

この実装で先ほどのテストをパスします。

写真とメガネを表示しているアプリ
写真とメガネを表示しているアプリ

リファクタリング

ContentView を使い続けるのは良くない気がするので、MainView に リネームしておきます。

# XCode のリネーム機能を使うと、Struct 名だけでなく、ファイル名や、呼び出し側(App) も修正してくれて便利です。

以下が、ここまでに作ってきたコードです。

PhotoGlassesApp.swift

MainView

この記事でできたこと

  • JPG/PNG を Image を使って重ねて表示
  • Accessibility ID を使って、テストコードから要素を取得し属性をテスト

次回

メガネを Drag で動かせるようにします。

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

コメントを残す

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