Sie können ML Kit verwenden, um Barcodes zu erkennen und zu decodieren.
Jetzt ausprobieren
- Probieren Sie die Beispiel-App aus, um sehen Sie sich ein Anwendungsbeispiel für diese API an.
Hinweis
- Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei ein:
pod 'GoogleMLKit/BarcodeScanning', '15.5.0'
- Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit dem
.xcworkspace
ML Kit wird ab Xcode-Version 12.4 unterstützt.
Richtlinien für Eingabebilder
-
Damit das ML Kit Barcodes genau lesen kann, müssen die Eingabebilder Folgendes enthalten: Barcodes, die durch ausreichende Pixeldaten dargestellt werden.
Die spezifischen Pixeldatenanforderungen hängen sowohl vom Typ und der darin codierten Datenmenge, da viele Barcodes unterstützen eine variable Größe. Im Allgemeinen sollte die kleinste sollte die Einheit des Barcodes mindestens 2 Pixel breit sein. 2-dimensionale Codes, 2 Pixel hoch.
EAN-13-Barcodes bestehen beispielsweise aus Balken und Leerzeichen, 2, 3 oder 4 Einheiten breit, sodass ein EAN-13-Barcode-Image idealerweise Balken und Leerzeichen enthalten, die mindestens 2, 4, 6 und 8 Pixel breit sind. Da eine EAN-13- Barcode insgesamt 95 Einheiten breit ist, sollte der Barcode mindestens 190 Einheiten haben. Pixel breit.
Kompaktere Formate wie PDF417 erfordern größere Pixelabmessungen für ML Kit zuverlässig lesen. Beispielsweise kann ein PDF417-Code bis zu 34 Breite „Wörter“ (17 Einheiten) in einer einzelnen Zeile, was im Idealfall mindestens 1156 Pixel breit.
-
Ein schlechter Bildfokus kann die Scangenauigkeit beeinträchtigen. Wenn Ihre App nicht akzeptable Ergebnisse erzielen, bitten Sie den Nutzer, das Bild erneut zu erfassen.
-
Für typische Anwendungen wird empfohlen, eine höhere wie 1280 x 720 oder 1920 x 1080, wodurch Barcodes aus größerer Entfernung zur Kamera lesbar sind.
In Anwendungen, bei denen die Latenz von entscheidender Bedeutung ist, können Sie jedoch indem Bilder mit einer niedrigeren Auflösung aufgenommen werden. dass der Barcode den Großteil des Eingabebilds ausmacht. Siehe auch Tipps zum Verbessern der Leistung in Echtzeit
1. Barcode-Scanner konfigurieren
Wenn Sie wissen, welche Barcodeformate Sie lesen möchten, können Sie die Geschwindigkeit verbessern des Barcode-Scanners ein, indem Sie ihn so konfigurieren, dass nur diese Formate gescannt werden.Um beispielsweise nur Aztec-Code und QR-Codes zu scannen, erstellen Sie eine
BarcodeScannerOptions
-Objekt wie im
folgendes Beispiel:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
Die folgenden Formate werden unterstützt:
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- 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 (
MLKBarcodeFormatEAN13
) - EAN-8 (
MLKBarcodeFormatEAN8
) - ITF (
MLKBarcodeFormatITF
) - QR-Code (
MLKBarcodeFormatQRCode
) - UPC-A (
MLKBarcodeFormatUPCA
) - UPC-E (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - Aztekischer Code (
MLKBarcodeFormatAztec
)
2. Eingabebild vorbereiten
Um Barcodes in einem Bild zu scannen, übergeben Sie das Bild alsUIImage
- oder
CMSampleBufferRef
zu process()
oder results(in:)
der BarcodeScanner
:
Erstellen Sie ein VisionImage
-Objekt mithilfe von UIImage
oder einem
CMSampleBuffer
Wenn du ein UIImage
verwendest, gehe so vor:
- Erstellen Sie ein
VisionImage
-Objekt mit derUIImage
. Geben Sie die richtige.orientation
an.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Wenn du ein CMSampleBuffer
verwendest, gehe so vor:
-
Geben Sie die Ausrichtung der Bilddaten an, die in der
CMSampleBuffer
So ermitteln Sie die Bildausrichtung:
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; } }
- Erstellen Sie ein
VisionImage
-Objekt mithilfe derCMSampleBuffer
-Objekt und 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. BarcodeScanner-Instanz abrufen
Rufen Sie eineBarcodeScanner
-Instanz 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 dann das Bild 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 Barcodescan erfolgreich ist, gibt der Scanner ein ArrayBarcode
-Objekte. Jedes Barcode
-Objekt steht für ein
der im Bild erkannt wurde. Für jeden Barcode finden Sie
Begrenzungskoordinaten im Eingabebild sowie die mit dem
Barcode. Wenn der Barcode-Scanner den Typ der Daten
Barcode codiert ist, können Sie ein Objekt mit geparsten Daten abrufen.
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 zum Verbessern der Leistung in Echtzeit
Wenn Sie Barcodes in einer Echtzeitanwendung scannen möchten, gehen Sie so vor: um optimale Framerates zu erzielen:
-
Nehmen Sie Eingaben nicht mit der nativen Auflösung der Kamera auf. Auf einigen Geräten ist das Erfassen von Eingaben mit nativer Auflösung extrem groß (10+ Megapixel), was zu einer sehr geringen Latenz führt, Genauigkeit. Fordern Sie stattdessen nur die erforderliche Größe von der Kamera an. für Barcode-Scanning, die normalerweise nicht mehr als 2 Megapixel beträgt.
Voreinstellungen für benannte Erfassungssitzungen:
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
, usw.) werden jedoch nicht empfohlen, da sie sich Auflösung nicht geeignet ist. Verwenden Sie stattdessen die spezifischen Voreinstellungen wieAVCaptureSessionPreset1280x720
.Wenn die Scangeschwindigkeit wichtig ist, können Sie die Bildaufnahme weiter verringern Problembehebung. Beachten Sie jedoch die Mindestanforderungen an die Größe von Barcodes. wie oben beschrieben.
Wenn Sie versuchen, Barcodes aus einer Streamingsequenz zu erkennen Videoframes gezeigt wird, kann die Erkennung von Frame zu Frame unterschiedliche Ergebnisse liefern. Frame. Sie sollten warten, bis Sie eine Reihe derselben um sicher zu sein, dass Sie ein gutes Ergebnis liefern.
Die Prüfsummenzahl wird für ITF und CODE-39 nicht unterstützt.
- Verwende zum Verarbeiten von Videoframes die synchrone
results(in:)
API des Detektors. Anruf diese Methode aus demAVCaptureVideoDataOutputSampleBufferDelegate
<ph type="x-smartling-placeholder"></ph>captureOutput(_, didOutput:from:)
-Funktion, um synchron Ergebnisse aus dem angegebenen Video abzurufen Frame. beibehalten vonAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
alstrue
, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer Videoframe verfügbar ist, während der Detektor ausgeführt wird, wird er verworfen. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken Eingabebild, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie das Bild in einem Schritt übereinanderlegen. Dadurch rendern Sie auf der Anzeigeoberfläche pro verarbeitetem Eingabeframe nur einmal. Weitere Informationen finden Sie im Abschnitt updatePreviewOverlayViewWithLastFrame. im Beispiel der ML Kit-Kurzanleitung finden Sie ein Beispiel.