Sie können mit ML Kit Barcodes erkennen und decodieren.
Ausprobieren
- Probieren Sie die Beispiel-App aus, um ein Beispiel für die Verwendung dieser API zu sehen.
Hinweis
- Nehmen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei auf:
pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
- Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit der zugehörigen
.xcworkspace
. ML Kit wird in Xcode ab Version 12.4 unterstützt.
Richtlinien für Eingabebilder
-
Damit ML Kit Barcodes genau lesen kann, müssen Eingabebilder Barcodes enthalten, die durch genügend Pixeldaten dargestellt werden.
Die spezifischen Pixeldatenanforderungen hängen sowohl vom Barcodetyp als auch von der darin codierten Datenmenge ab, da viele Barcodes eine Nutzlast mit variabler Größe unterstützen. Im Allgemeinen sollte die kleinste sinnvolle Einheit des Barcodes mindestens 2 Pixel breit und bei zweidimensionalen Codes 2 Pixel hoch sein.
EAN-13-Barcodes bestehen beispielsweise aus Balken und Leerzeichen, die 1, 2, 3 oder 4 Einheiten breit sind. Ein EAN-13-Barcodebild hat daher idealerweise Balken und Leerzeichen, die mindestens 2, 4, 6 und 8 Pixel breit sind. Da ein EAN-13-Barcode insgesamt 95 Einheiten breit ist, sollte der Barcode mindestens 190 Pixel breit sein.
Kompaktere Formate wie PDF417 benötigen größere Pixelabmessungen, damit ML Kit sie zuverlässig lesen kann. Ein PDF417-Code kann beispielsweise bis zu 34 „Wörter“ mit einer Breite von 17 Einheiten in einer einzelnen Zeile enthalten, die im Idealfall mindestens 1.156 Pixel breit sind.
-
Ein schlechter Bildfokus kann die Scangenauigkeit beeinträchtigen. Wenn deine App keine akzeptablen Ergebnisse erzielt, bitte den Nutzer, das Bild noch einmal aufzunehmen.
-
Für typische Anwendungen wird empfohlen, Bilder mit höherer Auflösung wie 1280 × 720 oder 1920 × 1080 bereitzustellen, damit Barcodes auch aus größerer Entfernung von der Kamera gescannt werden können.
In Anwendungen, bei denen die Latenz jedoch von entscheidender Bedeutung ist, können Sie die Leistung verbessern, indem Sie Bilder mit einer niedrigeren Auflösung aufnehmen, bei denen der Barcode aber den Großteil des Eingabebilds ausmachen muss. Weitere Informationen finden Sie unter Tipps zur Verbesserung der Echtzeitleistung.
1. Barcode-Scanner konfigurieren
Wenn Sie wissen, welche Barcodeformate Sie lesen möchten, können Sie die Geschwindigkeit des Barcodescanners verbessern, indem Sie ihn so konfigurieren, dass er nur diese Formate scannt.Wenn Sie beispielsweise nur Aztec-Code und QR-Codes scannen möchten, erstellen Sie ein BarcodeScannerOptions
-Objekt wie im folgenden Beispiel:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
Die folgenden Formate werden unterstützt:
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- Logo: ITF
- qrCode
- UPCA
- UPCE
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
Die folgenden Formate werden unterstützt:
- Code-128 (
MLKBarcodeFormatCode128
) - Code-39 (
MLKBarcodeFormatCode39
) - Code-93 (
MLKBarcodeFormatCode93
) - Codabar (
MLKBarcodeFormatCodaBar
) - Datenmatrix (
MLKBarcodeFormatDataMatrix
) - EAN-13-Nummer (
MLKBarcodeFormatEAN13
) - EAN-8 (
MLKBarcodeFormatEAN8
) - ITF (
MLKBarcodeFormatITF
) - QR-Code (
MLKBarcodeFormatQRCode
) - UPC-A (
MLKBarcodeFormatUPCA
) - UPC-E (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - Aztec-Code (
MLKBarcodeFormatAztec
)
2. Eingabebild vorbereiten
Um Barcodes in einem Bild zu scannen, übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
an die Methode process()
oder results(in:)
des BarcodeScanner
:
Erstellen Sie mit UIImage
oder CMSampleBuffer
ein VisionImage
-Objekt.
Wenn Sie ein UIImage
verwenden, gehen Sie so vor:
- Erstellen Sie mit
UIImage
einVisionImage
-Objekt. Achten Sie darauf, den richtigen.orientation
anzugeben.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Wenn Sie ein CMSampleBuffer
verwenden, gehen Sie so vor:
-
Gibt die Ausrichtung der Bilddaten an, die in
CMSampleBuffer
enthalten sind.So rufen Sie die Bildausrichtung ab:
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; } }
- Erstelle ein
VisionImage
-Objekt mit dem ObjektCMSampleBuffer
und der Ausrichtung: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. Instanz von BarcodeScanner abrufen
Rufen Sie eine Instanz vonBarcodeScanner
ab:
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. Bild verarbeiten
Übergeben Sie das Bild dann an die Methodeprocess()
:
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. Informationen aus Barcodes abrufen
Wenn der Barcode-Scan erfolgreich ist, gibt der Scanner ein Array vonBarcode
-Objekten zurück. Jedes Barcode
-Objekt stellt einen Barcode dar, der im Bild erkannt wurde. Für jeden Barcode können Sie seine Begrenzungskoordinaten im Eingabebild sowie die vom Barcode codierten Rohdaten abrufen. Wenn der Barcode-Scanner die Art der vom Barcode codierten Daten ermitteln konnte, können Sie außerdem ein Objekt abrufen, das geparste Daten enthält.
Beispiel:
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; } }
Tipps zur Verbesserung der Echtzeitleistung
Wenn Sie Barcodes in einer Echtzeitanwendung scannen möchten, beachten Sie die folgenden Richtlinien, um die besten Framerates zu erzielen:
-
Erfassen Sie Eingaben nicht mit der nativen Auflösung der Kamera. Auf einigen Geräten werden Eingaben in nativer Auflösung erfasst und extrem große Bilder (mehr als 10 Megapixel) erzeugt. Dies führt zu einer sehr schlechten Latenz, ohne dass die Genauigkeit verbessert wird. Fordern Sie stattdessen nur die Größe von der Kamera an, die zum Scannen des Barcodes erforderlich ist (normalerweise nicht mehr als 2 Megapixel).
Die benannten Voreinstellungen für Aufnahmesitzungen (
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
usw.) werden jedoch nicht empfohlen, da sie auf einigen Geräten ungeeigneten Auflösungen zugeordnet werden können. Verwenden Sie stattdessen die spezifischen Voreinstellungen wieAVCaptureSessionPreset1280x720
.Wenn die Scangeschwindigkeit wichtig ist, können Sie die Auflösung der Bilderfassung weiter senken. Beachten Sie jedoch die oben genannten Mindestanforderungen an die Barcodegröße.
Wenn Sie versuchen, Barcodes aus einer Abfolge von gestreamten Videoframes zu erkennen, kann die Erkennung von Frame zu Frame unterschiedliche Ergebnisse liefern. Sie sollten warten, bis Sie eine aufeinanderfolgende Reihe mit demselben Wert erhalten, um sicher zu sein, dass Sie ein gutes Ergebnis liefern.
Die Prüfsummenziffer wird für ITF und CODE-39 nicht unterstützt.
- Verwenden Sie zum Verarbeiten von Videobildern die synchrone
results(in:)
-API des Detektors. Rufen Sie diese Methode über diecaptureOutput(_, didOutput:from:)
-Funktion vonAVCaptureVideoDataOutputSampleBufferDelegate
auf, um synchron Ergebnisse aus dem angegebenen Videoframe zu erhalten. Behalten Sie diealwaysDiscardsLateVideoFrames
vonAVCaptureVideoDataOutput
alstrue
bei, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer Videoframe verfügbar wird, während der Detektor ausgeführt wird, wird er gelöscht. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken über das Eingabebild einzublenden, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie dann das Bild und Overlay in einem einzigen Schritt. Dadurch wird für jeden verarbeiteten Eingabeframe nur einmal ein Rendering auf der Anzeigeoberfläche ausgeführt. Ein Beispiel finden Sie unter updatePreviewOverlayViewWithLastFrame im ML Kit-Schnellstartbeispiel.