Mit ML Kit können Sie Barcodes erkennen und decodieren.
Hinweis
- Wenn Sie Firebase Ihrer App noch nicht hinzugefügt haben, folgen Sie der Anleitung im Einstiegsleitfaden.
- Fügen Sie die ML Kit-Bibliotheken in Ihre Podfile ein:
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit der.xcworkspace
. - Importieren Sie Firebase in Ihre App:
Swift
import Firebase
Objective-C
@import Firebase;
Richtlinien für Eingabebilder
-
Damit ML Kit Barcodes korrekt lesen kann, müssen die Eingabebilder Barcodes enthalten, die durch ausreichende Pixeldaten dargestellt werden.
Die spezifischen Anforderungen an die Pixeldaten hängen sowohl vom Barcodetyp als auch von der Menge der darin codierten Daten ab, da die meisten Barcodes eine Nutzlast mit variabler Länge unterstützen. Im Allgemeinen sollte die kleinste aussagekräftige Einheit des Barcodes mindestens 2 Pixel breit (und bei zweidimensionalen Codes 2 Pixel hoch) sein.
EAN-13-Barcodes bestehen beispielsweise aus Balken und Leerräumen, die 1, 2, 3 oder 4 Einheiten breit sind. Ein EAN-13-Barcodebild sollte daher idealerweise Balken und Leerräume mit einer Breite von mindestens 2, 4, 6 und 8 Pixeln haben. Da ein EAN-13-Barcode insgesamt 95 Einheiten breit ist, sollte er mindestens 190 Pixel breit sein.
Für dichtere Formate wie PDF417 sind größere Pixelabmessungen erforderlich, damit ML Kit sie zuverlässig lesen kann. Ein PDF417-Code kann beispielsweise bis zu 34 „Wörter“ mit 17 Einheiten in einer einzigen Zeile enthalten, die idealerweise mindestens 1.156 Pixel breit sein sollte.
-
Ein unscharfer Bildfokus kann die Scangenauigkeit beeinträchtigen. Wenn Sie keine zufriedenstellenden Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.
-
Für typische Anwendungen wird empfohlen, ein Bild mit höherer Auflösung (z. B. 1280 × 720 oder 1920 × 1080) bereitzustellen, damit Barcodes aus größerer Entfernung von der Kamera erkannt werden können.
Bei Anwendungen, bei denen die Latenz entscheidend ist, können Sie die Leistung jedoch verbessern, indem Sie Bilder mit niedrigerer Auflösung aufnehmen. Der Barcode muss dabei jedoch den Großteil des Eingabebilds ausmachen. Weitere Informationen finden Sie unter Tipps zur Verbesserung der Echtzeitleistung.
1. Barcode-Erkennung konfigurieren
Wenn Sie wissen, welche Barcodeformate gelesen werden sollen, können Sie die Geschwindigkeit des Barcode-Detektors verbessern, indem Sie ihn so konfigurieren, dass nur diese Formate erkannt werden.Wenn Sie beispielsweise nur Aztec-Code und QR-Codes erkennen möchten, erstellen Sie ein VisionBarcodeDetectorOptions
-Objekt wie im folgenden Beispiel:
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Die folgenden Formate werden unterstützt:
- Code128
- Code39
- Code93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- QR-Code
- PDF417
- Azteken
- DataMatrix
Objective-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Die folgenden Formate werden unterstützt:
- Code 128 (
FIRVisionBarcodeFormatCode128
) - Code 39 (
FIRVisionBarcodeFormatCode39
) - Code 93 (
FIRVisionBarcodeFormatCode93
) - Codabar (
FIRVisionBarcodeFormatCodaBar
) - EAN-13 (
FIRVisionBarcodeFormatEAN13
) - EAN-8 (
FIRVisionBarcodeFormatEAN8
) - ITF (
FIRVisionBarcodeFormatITF
) - UPC-A (
FIRVisionBarcodeFormatUPCA
) - UPC-E (
FIRVisionBarcodeFormatUPCE
) - QR-Code (
FIRVisionBarcodeFormatQRCode
) - PDF417 (
FIRVisionBarcodeFormatPDF417
) - Azteken (
FIRVisionBarcodeFormatAztec
) - Data Matrix (
FIRVisionBarcodeFormatDataMatrix
)
2. Barcode-Detektor ausführen
Wenn Sie Barcodes in einem Bild scannen möchten, übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
an die detect(in:)
-Methode der VisionBarcodeDetector
:
- Instanz von
VisionBarcodeDetector
abrufen: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];
-
Erstellen Sie ein
VisionImage
-Objekt mit einemUIImage
oder einemCMSampleBufferRef
.So verwenden Sie ein
UIImage
:- Drehen Sie das Bild bei Bedarf so, dass die Property
imageOrientation
auf.up
festgelegt ist. - Erstellen Sie ein
VisionImage
-Objekt mit dem korrekt gedrehtenUIImage
. Geben Sie keine Metadaten für die Drehung an. Es muss der Standardwert.topLeft
verwendet werden.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
So verwenden Sie ein
CMSampleBufferRef
:-
Erstellen Sie ein
VisionImageMetadata
-Objekt, das die Ausrichtung der Bilddaten imCMSampleBufferRef
-Puffer angibt.So rufen Sie die Bildausrichtung auf:
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; } }
Erstellen Sie dann das Metadatenobjekt:
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];
- Erstelle ein
VisionImage
-Objekt mit demCMSampleBufferRef
-Objekt und den Rotationsmetadaten:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Drehen Sie das Bild bei Bedarf so, dass die Property
-
Übergeben Sie dann das Bild an die
detect(in:)
-Methode: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. Informationen aus Barcodes abrufen
Wenn die Barcodeerkennung erfolgreich war, gibt der Detektor ein Array vonVisionBarcode
-Objekten zurück. Jedes VisionBarcode
-Objekt stellt einen Barcode dar, der im Bild erkannt wurde. Für jeden Barcode können Sie die Begrenzungskoordinaten im Eingabebild sowie die vom Barcode codierten Rohdaten abrufen. Wenn der Barcode-Detektor den Typ der vom Barcode codierten Daten ermitteln konnte, können Sie auch 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 (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; } }
Tipps zur Verbesserung der Echtzeitleistung
Wenn Sie Barcodes in einer Echtzeitanwendung scannen möchten, beachten Sie die folgenden Richtlinien, um die beste Framerate zu erzielen:
-
Erfassen Sie die Eingabe nicht mit der nativen Auflösung der Kamera. Auf einigen Geräten führt die Erfassung der Eingabe in der nativen Auflösung zu extrem großen Bildern (mehr als 10 Megapixel), was zu einer sehr schlechten Latenz führt, ohne dass die Genauigkeit verbessert wird. Fordere stattdessen nur die Größe von der Kamera an, die für die Barcodeerkennung erforderlich ist: in der Regel nicht mehr als 2 Megapixel.
Die benannten Presets für Aufnahmesitzungen (
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
usw.) werden jedoch nicht empfohlen, da sie auf einigen Geräten zu ungeeigneten Auflösungen führen können. Verwenden Sie stattdessen die speziellen Voreinstellungen wieAVCaptureSessionPreset1280x720
.Wenn die Scangeschwindigkeit wichtig ist, können Sie die Auflösung der Bildaufnahme weiter senken. Beachten Sie jedoch die oben genannten Mindestanforderungen an die Barcodegröße.
- Aufrufe an den Detektor drosseln Wenn während der Laufzeit des Detektors ein neuer Videoframe verfügbar wird, legen Sie ihn ab.
- Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. So wird für jeden Eingabeframe nur einmal auf die Displayoberfläche gerendert. Sehen Sie sich die Klassen previewOverlayView und FIRDetectionOverlayView in der Beispiel-App an.