ML Kit を使用すると、バーコードの認識やデコードができます。
試してみる
- サンプルアプリを試して、この API の使用例をご覧ください。
始める前に
- Podfile に次の ML Kit Pod を含めます。
pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
- プロジェクトの Pod をインストールまたは更新した後に、
.xcworkspace
を使用して Xcode プロジェクトを開きます。ML Kit は Xcode バージョン 12.4 以降でサポートされています。
入力画像に関するガイドライン
-
ML Kit でバーコードを正確に読み取るには、入力画像に含まれているバーコードが十分なピクセルデータによって表現されている必要があります。
多くのバーコードは可変サイズのペイロードをサポートしているため、特定のピクセルデータ要件は、バーコードの種類とエンコードされるデータの量によって異なります。一般に、バーコードの幅は 2 ピクセル以上にする必要があります。2 次元コードの場合は高さを 2 ピクセル以上にしてください。
たとえば、EAN-13 バーコードは幅が 1、2、3、4 のバーとスペースで構成されているため、EAN-13 バーコードの画像では、少なくとも 2、4、6、8 ピクセルのバーとスペースを使用することが理想的です。EAN-13 バーコードの幅は合計で 95 単位になるため、バーコードの幅は 190 ピクセル以上にする必要があります。
PDF417 のような高密度の形式を使用すると、ML Kit で読み取り精度を高めるため、より大きなピクセルサイズが必要になります。たとえば、PDF417 コードは 1 行に最大 34 個の 17 単位幅のワードを入れることができるため、1,156 ピクセル以上の幅が理想的です。
-
画像がぼやけていると、スキャン精度に影響する可能性があります。アプリが満足のいく結果を得られない場合は、ユーザーに画像をキャプチャし直すよう求めてください。
-
一般的なアプリケーションでは、カメラから遠く離れた位置からバーコードをスキャンできる、1280x720 や 1920x1080 などの高解像度の画像を使用することをおすすめします。
ただし、レイテンシが重要なアプリケーションでは、低解像度で画像をキャプチャすることでパフォーマンスを改善できますが、入力画像の大部分がバーコードである必要があります。リアルタイムのパフォーマンスを改善するためのヒントもご覧ください。
1. バーコード スキャナの設定
読み取るバーコード形式がわかっている場合は、その形式のみをスキャンするようにバーコード スキャナを構成することで、速度が向上します。たとえば、Aztec コードと QR コードのみをスキャンするには、次の例のように BarcodeScannerOptions
オブジェクトをビルドします。
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
次の形式がサポートされています。
- コード 128
- コード 39
- コード 93
- CodaBar
- データ マトリックス
- EAN13
- EAN8
- ITF
- QR コード
- UPCA
- 最大
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
次の形式がサポートされています。
- コード-128(
MLKBarcodeFormatCode128
) - コード-39(
MLKBarcodeFormatCode39
) - コード-93(
MLKBarcodeFormatCode93
) - Codabar(
MLKBarcodeFormatCodaBar
) - Data Matrix(
MLKBarcodeFormatDataMatrix
) - EAN-13(
MLKBarcodeFormatEAN13
) - EAN-8(
MLKBarcodeFormatEAN8
) - ITF(
MLKBarcodeFormatITF
) - QR コード(
MLKBarcodeFormatQRCode
) - UPC-A(
MLKBarcodeFormatUPCA
) - UPC-E(
MLKBarcodeFormatUPCE
) - PDF-417(
MLKBarcodeFormatPDF417
) - Aztec コード(
MLKBarcodeFormatAztec
)
2. 入力画像を準備する
画像内のバーコードをスキャンするには、画像をUIImage
または CMSampleBufferRef
として BarcodeScanner
の process()
メソッドまたは results(in:)
メソッドに渡します。
UIImage
または CMSampleBuffer
を使用して VisionImage
オブジェクトを作成します。
UIImage
を使用する場合の手順は次のとおりです。
UIImage
を使用して、VisionImage
オブジェクトを作成します。正しい.orientation
を指定してください。Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
CMSampleBuffer
を使用する場合の手順は次のとおりです。
-
CMSampleBuffer
に含まれる画像データの向きを指定します。画像の向きを取得するには:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
CMSampleBuffer
オブジェクトと向きを使用してVisionImage
オブジェクトを作成します。Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3.BarcodeScanner のインスタンスを取得する
BarcodeScanner
のインスタンスを取得します。
Swift
let barcodeScanner = BarcodeScanner.barcodeScanner() // Or, to change the default settings: // let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
Objective-C
MLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner]; // Or, to change the default settings: // MLKBarcodeScanner *barcodeScanner = // [MLKBarcodeScanner barcodeScannerWithOptions:options];
4. 画像を処理する
次に、画像をprocess()
メソッドに渡します。Swift
barcodeScanner.process(visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // Error handling return } // Recognized barcodes }
Objective-C
[barcodeScanner processImage:image completion:^(NSArray<MLKBarcode *> *_Nullable barcodes, NSError *_Nullable error) { if (error != nil) { // Error handling return; } if (barcodes.count > 0) { // Recognized barcodes } }];
5. バーコードから情報を取得する
バーコード スキャン オペレーションが成功すると、Barcode
オブジェクトの配列が返されます。各 Barcode
オブジェクトは画像内で検出されたバーコードを表します。バーコードごとに、入力画像の境界座標と、バーコードによってエンコードされた元データを取得できます。また、バーコード スキャナがバーコードによってエンコードされたデータのタイプを判別できた場合は、解析されたデータを含むオブジェクトも取得できます。
例:
Swift
for barcode in barcodes { let corners = barcode.cornerPoints let displayValue = barcode.displayValue let rawValue = barcode.rawValue let valueType = barcode.valueType switch valueType { case .wiFi: let ssid = barcode.wifi?.ssid let password = barcode.wifi?.password let encryptionType = barcode.wifi?.type case .URL: let title = barcode.url!.title let url = barcode.url!.url default: // See API reference for all supported value types } }
Objective-C
for (MLKBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; MLKBarcodeValueType valueType = barcode.valueType; switch (valueType) { case MLKBarcodeValueTypeWiFi: ssid = barcode.wifi.ssid; password = barcode.wifi.password; encryptionType = barcode.wifi.type; break; case MLKBarcodeValueTypeURL: url = barcode.URL.url; title = barcode.URL.title; break; // ... default: break; } }
リアルタイムのパフォーマンスを改善するためのヒント
リアルタイムのアプリケーションでバーコードをスキャンする場合は、適切なフレームレートを得るために次のガイドラインに従ってください。
-
カメラのネイティブ解像度で入力をキャプチャしないでください。一部のデバイスでは、ネイティブ解像度で入力をキャプチャすると、非常に大きい(10 メガピクセル以上の)画像が生成されます。レイテンシが非常に低くなるだけで精度が向上するわけではありません。代わりに、バーコード スキャンに必要なサイズをカメラからリクエストしてください。サイズは通常 2 メガピクセル以下です。
指定されたキャプチャ セッション プリセット(
AVCaptureSessionPresetDefault
、AVCaptureSessionPresetLow
、AVCaptureSessionPresetMedium
など)はおすすめできませんが、一部のデバイスで、不適切な解像度に割り当てられることがあります。代わりに、AVCaptureSessionPreset1280x720
などの特定のプリセットを使用してください。スキャン速度が重要な場合は、画像キャプチャの解像度をさらに下げることができます。ただし、上記の最小バーコード サイズの要件に注意してください。
ストリーミング動画フレームのシーケンスからバーコードを認識しようとすると、認識機能によってフレームごとに異なる結果が生成されます。同じ値が連続して返されるまで待ってから、適切な結果が返されることを確認します。
チェックサム ディジットは ITF と CODE-39 ではサポートされていません。
- 動画フレームを処理するには、検出器の
results(in:)
同期 API を使用します。AVCaptureVideoDataOutputSampleBufferDelegate
のcaptureOutput(_, didOutput:from:)
関数からこのメソッドを呼び出して、特定の動画フレームから結果を同期的に取得します。AVCaptureVideoDataOutput
のalwaysDiscardsLateVideoFrames
をtrue
として保持し、検出器の呼び出しのスロットリングを行います。検出器の実行中に新しい動画フレームが使用可能になると、そのフレームは破棄されます。 - 検出器の出力を使用して入力画像の上にグラフィックスをオーバーレイする場合は、まず ML Kit から検出結果を取得し、画像とオーバーレイを 1 つのステップでレンダリングします。これにより、ディスプレイ サーフェスへのレンダリングは、処理された入力フレームごとに 1 回で済みます。例については、ML Kit クイックスタート サンプルの updatePreviewOverlayViewWithLastFrame をご覧ください。