LoginSignup
26
19

More than 1 year has passed since last update.

WWDC22、iOS16:iOSアプリに画像からテキストを選択する機能を追加(VisionKit)

Last updated at Posted at 2022-06-20

※一般公開されているWWDC Keynoteの動画と公開Session/Documentation/Sample Codeページだけを使ってこの記事を執筆しました。

iOS 16でVisionKitフレームワークを使用することで、あなたのアプリはわずか数行のコードでカメラストリームからリアルタイムにテキストを認識できます(日本語にも対応しています)。

image-text-extraction.jpeg

例えば、これはApple WWDCのセッションビデオからのスキャンシーンです。

スマホを動かすと、フォーカスしている領域が変化する。
フォーカスされた部分はハイライト表示されます。
そして、ユーザーがフォーカスされた部分をタップすると、認識されたコンテンツがデリゲート(DataScannerViewControllerDelegate)経由で配信されます。

また、機械読み取り可能なコードのみをスキャナーに探させることも可能です。

これは、例えばQRコードをスキャンするアプリ機能を構築している場合に特に有効です。

ライブカメラストリームの代わりに、完全なスキャンを行うための画像をAPIに提供することも可能です。
ユーザーは、認識された結果からテキストをコピーすることを選択できます(画像自体にオーバーレイ表示されます)。

このAPIは主にUIKitで利用できるので、この記事ではまずUIKit (StoryBoard)でこれらの機能を実装し、その後SwiftUI対応のビューを作成することについて話します。

この記事で紹介するフレームワークは、Xcode 14 betaとiOS 16のシミュレータ/デバイスで動作します。

ライブカメラスキャン

上記の1つ目と2つ目のデモ画像に示すように、ライブカメラストリームを使用して、興味のあるコンテンツをスキャンすることができます。
興味のあるコンテンツを定義する(recognizedDataTypes)ことができるので、システムは関連するコンテンツのみをハイライトします。
例えば、すべてのテキストをスキャンするか、電話番号だけをスキャンするかを設定できます。
また、機械読み取り可能なコード(QRコードやバーコードなど)をスキャンするように定義することもできます。

まず、カメラアクセス許可の説明文字列 NSCameraUsageDescriptionInfo.plist に追加します。

次に、VisionKit フレームワークをインポートします。

データスキャナが利用可能かどうかは DataScannerViewController.isSupportedDataScannerViewController.isAvailable を使って確認する。

次に、データスキャナ DataScannerViewController を初期化することで、スキャンインターフェースを提示する。

@IBAction func actionShowDataScanner() {
    let scannerVC = DataScannerViewController(
        recognizedDataTypes: [.text()],
            qualityLevel: .fast,
            recognizesMultipleItems: false,
            isHighFrameRateTrackingEnabled: false,
            isGuidanceEnabled: true,
            isHighlightingEnabled: true
    )
    scannerVC.delegate = self
    try? scannerVC.startScanning()
    self.present(scannerVC, animated: true)
}

recognizedDataTypes

これは、認識したいデータの種類を定義します。

recognizedDataTypes: [.text(languages: ["ja"])]: 日本語のテキストを認識することを意味する。
他の言語の入力をISOフォーマットで指定することもできます。値を指定しない場合は、システムで設定されているユーザー優先言語が使用されます。

また、スキャンしたいコンテンツの種類を定義することができます。例:recognizedDataTypes: [.text(languages: ["ja"], textContentType: .telephoneNumber)] は、電話番号のスキャンを意味します。

その他のコンテンツタイプとしては、日時をスキャンする dateTimeDuration
メールアドレスをスキャンする emailAddress
フライト番号をスキャンする flightNumber
住所をスキャンする fullStreetAddress
郵便物の追跡番号をスキャンする shipmentTrackingNumber
URLをスキャンする URL などがあります。

また、機械読み取り可能なコード(バーコードやQRコード)を検索させることもできる。

recognizedDataTypes: [.barcode()]

このコードはバーコードを読み取りますが、QRコードも動作することが確認されています。

DataScannerViewControllerDelegateデリゲートの設定とタップされた結果の受信

ユーザーがハイライト部分をタップすると、デリゲート内で didTapOn 関数が呼び出されます。ここでは、テキストの内容(transcript、つまり画像から認識された文字列)、またはバーコードのペイロード文字列を読み取ることができます。

extension ViewController: DataScannerViewControllerDelegate {
    
    func dataScanner(_ dataScanner: DataScannerViewController, didTapOn item: RecognizedItem) {
        switch item {
        case .text(let text):
            print(text.transcript)
        case .barcode(let barcode):
            print(barcode.payloadStringValue)
        }
    }
    
}

その他の構成

data_scanner_config.jpg

構成 説明
.qualityLevel スキャナがデータを見つけるために使用する解像度。
.recognizesMultipleItems スキャナがライブ映像内のすべてのアイテムを識別すべきかどうかを示すbool値。
.isHighFrameRateTrackingEnabled スキャナが認識したアイテムのジオメトリを更新する頻度を決定するbool値。
.isPinchToZoomEnabled ユーザーが2本指のピンチインズームジェスチャーを使用できるかどうかを示すbool値。
.isGuidanceEnabled スキャナが項目を選択する際に、ユーザーにヘルプを提供するかどうかを示すbool値。
.isHighlightingEnabled スキャナが認識した項目の周囲にハイライトを表示するかどうかを示すbool値。

フルイメージスキャン

ライブカメラストリームの代わりに、静止画像(撮影した写真や保存した画像)をスキャンしてすべてのテキストを調べ、ユーザーがテキストを選択できるようにすることもできます。

そのためには、画像ビューの上に分析結果をオーバーレイする必要があります。そのため、まずUIImageViewを作成する必要があります。この例では、UIStoryBoardを使い、UIImageViewのアウトレットを追加、リンクしています。

@IBOutlet weak var imageView: UIImageView!

次に、画像解析に関連する変数を追加します。

let analyzer = ImageAnalyzer()
let interaction = ImageAnalysisInteraction()

ビューがセットアップされたら、UIImageViewに解析オーバーレイ(interactionと呼びます)を追加します。

imageView.addInteraction(interaction)

新しい画像が手に入ったら、その画像をUIImageViewに更新し、前回の解析結果をクリアして、関数を呼び出して画像解析を実行します。

// Clear previous analysis
interaction.preferredInteractionTypes = []
interaction.analysis = nil
// Apply new image and start analyzing
self.imageView.image = imageObj
self.analyzeCurrentImage()
func analyzeCurrentImage() {
        guard let image = imageView.image else {
            return
        }
        Task {
            let configuration = ImageAnalyzer.Configuration([.text, .machineReadableCode])
            do {
                let analysis = try await analyzer.analyze(image, configuration: configuration)
                if let analysis = analysis {
                    interaction.analysis = analysis
                    interaction.preferredInteractionTypes = .textSelection
                }
            }
            catch {
                print(error)
            }
        }
    }

上記の関数では、テキストと機械可読コードをスキャンする必要があることを定義したコンフィギュレーションを設定します。
解析が完了するのを待つために、await キーワードを使用します。
そして、解析結果をinteractionオブジェクトに保存します(これは画像オブジェクトにオーバーレイとして表示されます)。

IMG_1184.PNG

解析が完了すると、画面右下にテキスト変換のアイコンが表示されます。

scanning-button-visionkit.png

これで、認識されたテキストエリアがハイライト表示されるはずです。ユーザーは長押しして選択し、コピーすることができます。

interaction.allowLongPressForDataDetectorsInTextModeを設定すると、認識結果が出たときに、ユーザーが直接テキストを長押しして選択できるようになります。

また、interaction.selectableItemsHighlightedを設定すると、認識プロセスが完了したときに、項目が自動的にハイライトされます。

SwiftUIとの互換性

私は、DataScannerViewControllerビューコントローラとして表現可能(SwiftUIでシートとして表示可能)、
ImageAnalysisInteractionビューとして表現可能(SwiftUIで直接表示可能)に
ラップしたライブラリをオープンソースとして公開しています。


:thumbsup: お読みいただきありがとうございました。

☺️ Twitter @MszPro
🐘 Mastodon @me@mszpro.com

:sunny:


writing-quickly_emoji_400.png

Written by MszPro~


関連記事

UICollectionViewの行セル、ヘッダー、フッター、またはUITableView内でSwiftUIビューを使用(iOS 16, UIHostingConfiguration)

iPhone 14 ProのDynamic Islandにウィジェットを追加し、Live Activitiesを開始する(iOS16.1以降)

iOS 16:秘密値の保存、FaceID認証に基づく個人情報の表示/非表示(LARight)

iOS16 MapKitの新機能 : 地図から場所を選ぶ、通りを見回す、検索補完

SwiftUIアプリでバックグラウンドタスクの実行(ネットワーク、プッシュ通知) (BackgroundTasks, URLSession)

WWDC22、iOS16:iOSアプリに画像からテキストを選択する機能を追加(VisionKit)

WWDC22、iOS16:数行のコードで作成できるSwiftUIの新機能(26本)

WWDC22、iOS 16:SwiftUIでChartsフレームワークを使ってチャートを作成する

WWDC22, iOS 16: WeatherKitで気象データを取得

WWDC 2022の基調講演のまとめ記事

26
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
19