您可以使用 ML Kit 辨識條碼並加以解碼。
立即試用
- 使用範例應用程式試試 請查看此 API 的使用範例。
事前準備
- 在 Podfile 中加入下列 ML Kit Pod:
pod 'GoogleMLKit/BarcodeScanning', '15.5.0'
- 安裝或更新專案的 Pod 後,請使用
.xcworkspace
。Xcode 12.4 以上版本支援 ML Kit。
輸入圖片規範
-
為了讓 ML Kit 準確讀取條碼,輸入圖片必須包含 以充足的像素資料表示條碼
具體的像素資料規定取決於 包括條碼和編碼的資料量,因為許多條碼 可支援可變大小酬載一般來說,最小的 條碼單位寬度至少須為 2 像素,而 2 維代碼,高度為 2 像素。
舉例來說,EAN-13 條碼是由 1 號的酒吧和空格組成。 寬 2、3 或 4 個單位,因此在理想情況下,EAN-13 條碼圖片應有長條 顯示寬度至少為 2、4、6 和 8 像素的空間。因為 EAN-13 條碼的總寬為 95 個單位,條碼至少應為 190 像素寬。
密度格式 (例如 PDF417) 需要更大的像素尺寸 可靠的機器學習套件例如,PDF417 程式碼最多可包含 寬 34 個 17 單位的「words」理想情況下 1156 像素寬。
-
圖像對焦品質不佳可能會影響掃描的準確度。如果應用程式無法 可接受的結果,請使用者重新拍攝圖片。
-
建議您為一般應用程式提供 解析度圖片,例如 1280x720 或 1920x1080,才能製作條碼 從遠一點的相機鏡頭掃描即可。
不過,若是應用程式比較注重延遲狀況,您可以提高 低解析度的圖像,但我們需要 條碼構成大部分的輸入圖片另請參閱 即時效能改善秘訣。
1. 設定條碼掃描器
如果您知道預期會讀取哪些條碼格式,則可加快速度 方法是設定僅掃描這些格式舉例來說,如果只要掃描 Aztec 代碼和 QR code,請建立
BarcodeScannerOptions
物件,如
範例:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
支援下列格式:
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- ITF
- qrCode
- UPCA
- UPCE
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
支援下列格式:
- 代碼-128 (
MLKBarcodeFormatCode128
) - 代碼-39 (
MLKBarcodeFormatCode39
) - 代碼-93 (
MLKBarcodeFormatCode93
) - 科達巴 (
MLKBarcodeFormatCodaBar
) - 資料矩陣 (
MLKBarcodeFormatDataMatrix
) - EAN-13 (
MLKBarcodeFormatEAN13
) - EAN-8 (
MLKBarcodeFormatEAN8
) - ITF (
MLKBarcodeFormatITF
) - QR code (
MLKBarcodeFormatQRCode
) - 通用產品代碼 (
MLKBarcodeFormatUPCA
) - UPC-E (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - Aztec 代碼 (
MLKBarcodeFormatAztec
)
2. 準備輸入圖片
如要掃描圖片中的條碼,請以UIImage
或
將 CMSampleBufferRef
設為 BarcodeScanner
的 process()
或 results(in:)
方法:
使用 UIImage
或VisionImage
CMSampleBuffer
。
如果您使用 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; } }
- 使用
VisionImage
CMSampleBuffer
物件和方向: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+ 才能確保延遲時間極短,而且 準確度。請改為只從必要的相機要求大小 通常不超過 200 萬像素。
已命名的擷取工作階段預設設定:
AVCaptureSessionPresetDefault
、AVCaptureSessionPresetLow
、AVCaptureSessionPresetMedium
、 等) 並不會使用,不過它們可以對應至 解析度不適合某些裝置。請改用我們 例如AVCaptureSessionPreset1280x720
。如果掃描速度很重要,可以進一步降低圖片拍攝速度 解析度。但請注意,條碼大小下限規定 即可。
如果您嘗試從串流序列中辨識條碼 辨識器可能會針對不同影格產生不同結果 相框。您應等待系統連續收到相同的一系列相同的 ,這樣很有自信會提供最佳結果。
ITF 和 CODE-39 不支援總和檢查碼。
- 如要處理影片影格,請使用偵測工具的
results(in:)
同步 API。致電 透過AVCaptureVideoDataOutputSampleBufferDelegate
的captureOutput(_, didOutput:from:)
函式,以同步方式取得指定影片的結果 相框。保留AVCaptureVideoDataOutput
的alwaysDiscardsLateVideoFrames
做為true
,以限制對偵測工具的呼叫。如果是 影格的畫面,就會遭到捨棄。 - 如果使用偵測工具的輸出內容將圖像重疊 先從 ML Kit 取得結果,然後算繪圖片 並疊加單一步驟這麼一來,您的應用程式就會算繪到顯示途徑 每個處理的輸入影格只會產生一次請參閱 updatePreviewOverlayViewWithLastFrame 也可以查看一個範例