您可以使用 ML Kit 辨識條碼並加以解碼。
事前準備
- 如果尚未將 Firebase 加入應用程式,請按照下列步驟操作: 入門指南中的步驟。
- 在 Podfile 中加入 ML Kit 程式庫:
敬上 安裝或更新專案的 Pod 後,請務必開啟 Xcode 專案pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
.xcworkspace
。 - 在應用程式中匯入 Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
輸入圖片規範
-
為了讓 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,請建立
VisionBarcodeDetectorOptions
物件,如
範例:
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
支援下列格式:
- 代碼 128
- 代碼 39
- 代碼 93
- 科達巴
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- QR code
- PDF417
- 阿茲特克
- DataMatrix
Objective-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
支援下列格式:
- 代碼 128 (
FIRVisionBarcodeFormatCode128
) - 代碼 39 (
FIRVisionBarcodeFormatCode39
) - 代碼 93 (
FIRVisionBarcodeFormatCode93
) - 科達巴 (
FIRVisionBarcodeFormatCodaBar
) - EAN-13 (
FIRVisionBarcodeFormatEAN13
) - EAN-8 (
FIRVisionBarcodeFormatEAN8
) - ITF (
FIRVisionBarcodeFormatITF
) - 通用產品代碼 (
FIRVisionBarcodeFormatUPCA
) - UPC-E (
FIRVisionBarcodeFormatUPCE
) - QR code (
FIRVisionBarcodeFormatQRCode
) - PDF417 (
FIRVisionBarcodeFormatPDF417
) - 阿茲特克 (
FIRVisionBarcodeFormatAztec
) - 資料矩陣 (
FIRVisionBarcodeFormatDataMatrix
)
2. 執行條碼偵測工具
如要掃描圖片中的條碼,請以UIImage
或
CMSampleBufferRef
到VisionBarcodeDetector
的detect(in:)
方法:
- 取得
VisionBarcodeDetector
的執行個體:Swift
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector]; // Or, to change the default settings: // FIRVisionBarcodeDetector *barcodeDetector = // [vision barcodeDetectorWithOptions:options];
-
使用
UIImage
或VisionImage
CMSampleBufferRef
。如何使用
UIImage
:- 視需要旋轉圖片,使其
imageOrientation
屬性為.up
。 - 使用正確旋轉的做法建立
VisionImage
物件UIImage
。請勿指定任何輪替中繼資料 (預設值) 值 (.topLeft
),則必須使用。Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
如何使用
CMSampleBufferRef
:-
建立
VisionImageMetadata
物件,以指定 包含的圖片資料方向CMSampleBufferRef
緩衝區。如何取得圖片方向:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
然後,建立中繼資料物件:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- 請使用
VisionImage
CMSampleBufferRef
物件和輪替中繼資料:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- 視需要旋轉圖片,使其
-
接著,將圖片傳遞至
detect(in:)
方法:Swift
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Objective-C
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. 透過條碼取得資訊
如果條碼辨識作業成功,偵測工具會傳回VisionBarcode
物件。每個 VisionBarcode
物件都代表
在圖片中偵測到的條碼針對每個條碼
輸入圖像中的邊界座標,以及由
條碼此外,如果條碼偵測工具可以判斷資料類型
您可以取得包含剖析資料的物件。
例如:
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 (FIRVisionBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; FIRVisionBarcodeValueType valueType = barcode.valueType; switch (valueType) { case FIRVisionBarcodeValueTypeWiFi: // ssid = barcode.wifi.ssid; // password = barcode.wifi.password; // encryptionType = barcode.wifi.type; break; case FIRVisionBarcodeValueTypeURL: // url = barcode.URL.url; // title = barcode.URL.title; break; // ... default: break; } }
即時效能改善訣竅
如要在即時應用程式中掃描條碼,請按照下列指示操作: 實現最佳影格速率:
-
請勿以相機原始解析度擷取輸入內容。在部分裝置上, 以原生解析度擷取輸入內容會產生極大檔案 (10+ 才能確保延遲時間極短,而且 準確度。請改為只從必要的相機要求大小 通常不超過 200 萬像素。
已命名的擷取工作階段預設設定:
AVCaptureSessionPresetDefault
、AVCaptureSessionPresetLow
、AVCaptureSessionPresetMedium
、 等) 並不會使用,不過它們可以對應至 解析度不適用於部分裝置。請改用我們 例如AVCaptureSessionPreset1280x720
。如果掃描速度很重要,可以進一步降低圖片拍攝速度 解析度。但請注意,條碼大小下限規定 即可。
- 限制對偵測工具的呼叫。如果新的影片影格 因此請在偵測器執行時捨棄影格。
- 使用偵測工具的輸出內容將圖像重疊 先從 ML Kit 取得結果,然後算繪圖片 並疊加單一步驟這麼一來,您的應用程式就會算繪到顯示途徑 每個輸入影格只能建立一次請參閱 previewOverlayView 和 FIRDetectionOverlayView 例如,在展示範例應用程式中使用類別。