🖼️

VisionKitで自動画像切り抜き(Subject Lifting)

2023/12/25に公開

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


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

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

https://developer.apple.com/videos/play/wwdc2023/10048/

https://developer.apple.com/videos/play/wwdc2023/10176

詳しくは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で実際に動かしてみました。コードは最小実装で示したものと同じです。

なお実装していて気付いたのですが、ImageAnalysisInteractionselectableItemsHighlightedtrue を設定していると、サブジェクトリフティングが効かないようです。

visionOS

本機能はvisionOS 1.0+でも利用可能です。

脚注
  1. 12/25時点で未投稿だったため「代わりに投稿」させていただきました。 ↩︎

Discussion