見出し画像

[iOS 17] VisionKitで画像切り抜き #WWDC23

iOS 16で標準の「写真」アプリに搭載され、多くのユーザーに歓迎された画像切り抜き機能ですが、iOS 17ではそれらに関連するAPIが追加されました。我々のアプリにも標準の写真アプリと同等の機能・体験をめちゃくちゃ簡単に、場合によってはコードを1行も追加することなく実装することができます。

iOS 16の写真からの切り抜き機能

関連するWWDC23のセッションは以下2つ。

詳しくはWWDCの上記セッションを見ていただければいいのですが、個人的に重要と思った点や実際にiOS 17実機で動かしてみて気付いた点などをまとめます。(Visionについては別記事に書きたいと思います。)

なお最後にサンプルコードも添付しています。

最小実装

iOS 16では、VisionKitに ImageAnalysis / ImageAnalysisInteraction クラスが追加され、次のような非常にシンプルなコードで、画像内のテキスト認識などが非常に簡単に実装できるようになりました。

let configuration = ImageAnalyzer.Configuration([.text])
let analysis = try await imageAnalyzer.analyze(image, configuration: configuration)
imageAnalysisInteraction.analysis = analysis
imageAnalysisInteraction.preferredInteractionTypes = [.automatic]

UIImageViewにaddInteractionすると、

imageView.addInteraction(imageAnalysisInteraction)

次のように画像内のテキストを抽出し、インタラクションできるようになる(もちろんプログラムからテキストを取得できる)というものでした。

(こちらの機能は日本語もサポートしており、サクッとOCRを使ったアプリを実装したい場合には非常に重宝する機能追加でした。)

で、iOS 17の画像切り抜き機能の最小実装方法ですが、なんと、上のコードそのまんまで画像切り抜きも行えるようになります。冒頭で「場合によっては1行も追加することなく」と書いたのはそのためです。

理由としては、`preferredInteractionTypes` に指定した .automatic (iOS 16の頃からある)が、そのままiOS 17ではSubject lifting(画像内の物体を持ち上げる機能)もサポートしているためです。

What's new in VisionKitより

明示的にテキスト認識やQRコード認識等だけサポートしたい場合は .automaticTextOnly, 画像切り抜きだけサポートしたい場合は .imageSubject というタイプを指定することもできます。これらはいずれもiOS 17で追加されたものです。

パフォーマンスへの配慮

"What's new in VisionKit"で解説されていたのですが、

This is because in order to preserve power and performance, Subject Lifting analysis is handled separately by the interaction after the initial analysis is complete.

パワーとパフォーマンスの維持のため、サブジェクトリフティング分析は、最初の分析が完了した後、インタラクションによって個別に処理される、とのことです。

またこれにより

This means you don't need to handle the case of the user swiping though many photos. The interaction will handle this for you. All you need to do is ensure you have an appropriate interaction type set-- in this case, automatic-- and the rest is handled by the interaction.

ユーザーが多くの写真をスワイプしているようなケースを処理する必要はない、とのこと。(こういうインタラクションの交通整理を勝手にやってくれるのは大変ありがたい)

ちなみに、これを読んで、もしかしたらサブジェクトリフティングだけやりたい場合は ImageAnalyzer クラスの analyze メソッドを呼ぶ必要もないのか?と試してみましたが、それはダメでした。リフティングの処理は個別にインタラクションに応じて個別に行われるとはいえ、analyzeメソッドによる分析結果は何らかの形で内部で利用されているようです。

実機でのデモ

iOS 17で実際に動かしてみました。コードは最小実装で示したものと同じです。

ここから先は

122字 / 1画像 / 1ファイル
WWDC23だけでなく、WWDC22についても書いていきます。

WWDC 2023やiOS 17についてセッションやサンプルを見つつ勉強したことを記事にしていくマガジンです。また昨年キャッチアップをお休…

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/