0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

QRコードの画像からデータを読み取る

Posted at

はじめに

QRコードの読み取りはiOSアプリで頻繁に登場する機能です。
カメラをQRコードに向けて読み取る方法一般的です
しかし、画面に表示されているQRコードはカメラ向けられず、困った経験のある方もいるのではないでしょうか?
今回は、画像データとしてのQRコードを読み取る方法を紹介します。

環境

  • OS: macOS Sonoma 14.7.1
  • XCode: 16.2.0

実装方針

VisionフレームワークにあるNVImageRequestHandlerVNDetectBarcodesRequestを利用します。
VNDetectBarcodesRequestでは、処理を待つためにクロージャーを利用しなければなりませんが、今回はwithCheckedThrowingContinuationを利用してasync関数として定義することにします。

VNImageRequestHandler

VNImageRequestHandlerを利用すると、単一の画像に対して1つ以上の処理をリクエストできます。
イニシャライザに画像データを渡す形で初期化し、performメゾットを利用することで処理をリクエストできます。
イニシャライザは、渡す画像データの型によって複数種類用意されており、CIImageUIImage, Dataなどを利用できます。

VNDetectBarcodesRequest

VNDetectBarcodesRequestはVisionフレームワークによって提供されており、画像内のバーコード検出機能を提供しています。
このクラスをVNImageRequestHandler.performの引数とすることで、画像データの解析時に任意の処理を指せることができます

実装

サンプルとして、引数にQRコード画像をData型に変換したものを渡すと、QRコードのPayloadを返す関数を作成してみます。

func detectQRCode(imageData: Data) async throws -> String {
    // withCheckedThrowingContinuationを利用して、asyncな関数に変換
    return try await withCheckedThrowingContinuation { continuation in
        // VNDetectBarcodesrequestを利用して、画像解析時の処理を定義する
        let request = VNDetectBarcodesRequest { request, error in
            if let error {
                continuation.resume(throwing: error)
                return
            }

            guard let results = request.results as? [VNBarcodeObservation],
                let payload = results.first?.payloadStringValue else {
                    continuation.resume(throwing: HogeError.payloadNotFound) // 読み込めない場合には任意のえらーをthrowする 
                    return
                }
            continuation.resume(returning: payload)
        }

        // VNImagerequestHandlerのイニシャライザに、解析したいQRコード画像のデータを渡す
        let handler = VNImageRequestHandler(data: imageData, options: [:])
        do {
            // perform関数の実行によって解析を開始し、NVDetectBarcodesRequestに定義した内容に従って処理が行われる
            try handler.perform([request])
        } catch {
            continuation.resume(throwing: error)
        }
    }
}

まとめ

要件によってはカメラからのQRコード読み込みと合わせて実装することで、よりQRコード読み込みを便利にできると思います!
実装コストも低いので是非試してみてください!

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?