Mit dem ML Kit können Sie Barcodes erkennen und dekodieren.
Bevor Sie beginnen
- Wenn Sie Firebase noch nicht zu Ihrer App hinzugefügt haben, befolgen Sie dazu die Schritte im Leitfaden „Erste Schritte“ .
- Fügen Sie die ML-Kit-Bibliotheken in Ihre Pod-Datei ein:
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, stellen Sie sicher, dass Sie Ihr Xcode-Projekt mit seinem.xcworkspace
öffnen. - Importieren Sie Firebase in Ihre App:
Schnell
import Firebase
Ziel c
@import Firebase;
Geben Sie Bildrichtlinien ein
Damit ML Kit Barcodes genau lesen kann, müssen Eingabebilder Barcodes enthalten, die durch ausreichend Pixeldaten dargestellt werden.
Die spezifischen Pixeldatenanforderungen hängen sowohl von der Art des Barcodes als auch von der darin codierten Datenmenge ab (da die meisten Barcodes eine Nutzlast variabler Länge unterstützen). Im Allgemeinen sollte die kleinste aussagekräftige Einheit des Barcodes mindestens 2 Pixel breit (und bei 2-dimensionalen Codes 2 Pixel hoch) sein.
EAN-13-Barcodes bestehen beispielsweise aus Strichen und Zwischenräumen mit einer Breite von 1, 2, 3 oder 4 Einheiten. Daher weist ein EAN-13-Barcodebild idealerweise Striche und Zwischenräume mit einer Breite von mindestens 2, 4, 6 und auf 8 Pixel breit. Da ein EAN-13-Barcode insgesamt 95 Einheiten breit ist, sollte der Barcode mindestens 190 Pixel breit sein.
Dichtere Formate wie PDF417 benötigen größere Pixelabmessungen, damit ML Kit sie zuverlässig lesen kann. Beispielsweise kann ein PDF417-Code bis zu 34 „Wörter“ mit einer Breite von 17 Einheiten in einer einzelnen Zeile enthalten, die idealerweise mindestens 1156 Pixel breit wäre.
Eine schlechte Bildschärfe kann die Scangenauigkeit beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erhalten, bitten Sie den Benutzer, das Bild erneut aufzunehmen.
Für typische Anwendungen wird empfohlen, ein Bild mit höherer Auflösung (z. B. 1280 x 720 oder 1920 x 1080) bereitzustellen, damit Barcodes aus größerer Entfernung von der Kamera erkennbar sind.
Bei Anwendungen, bei denen die Latenz entscheidend ist, können Sie die Leistung jedoch verbessern, indem Sie Bilder mit einer niedrigeren Auflösung erfassen, aber verlangen, dass der Barcode den Großteil des Eingabebilds ausmacht. Siehe auch Tipps zur Verbesserung der Echtzeitleistung .
1. Konfigurieren Sie den Barcode-Detektor
Wenn Sie wissen, welche Barcode-Formate Sie voraussichtlich lesen werden, können Sie die Geschwindigkeit des Barcode-Detektors verbessern, indem Sie ihn so konfigurieren, dass er nur diese Formate erkennt. Um beispielsweise nur Aztec-Code und QR-Codes zu erkennen, erstellen Sie ein VisionBarcodeDetectorOptions
Objekt wie im folgenden Beispiel:
Schnell
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Folgende Formate werden unterstützt:
- Code128
- Code39
- Code93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- QR-Code
- PDF417
- aztekisch
- Datenmatrix
Ziel c
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Folgende 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
) - Aztec (
FIRVisionBarcodeFormatAztec
) - Datenmatrix (
FIRVisionBarcodeFormatDataMatrix
)
2. Starten Sie den Barcode-Detektor
Um Barcodes in einem Bild zu scannen, übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
an die Methode detect(in:)
von VisionBarcodeDetector
:- Holen Sie sich eine Instanz von
VisionBarcodeDetector
:Schnell
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Ziel 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 seine
imageOrientation
Eigenschaft.up
hat. - Erstellen Sie ein
VisionImage
Objekt mit dem korrekt gedrehtenUIImage
. Geben Sie keine Rotationsmetadaten an – der Standardwert.topLeft
muss verwendet werden.Schnell
let image = VisionImage(image: uiImage)
Ziel c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
So verwenden Sie ein
CMSampleBufferRef
:Erstellen Sie ein
VisionImageMetadata
Objekt, das die Ausrichtung der imCMSampleBufferRef
Puffer enthaltenen Bilddaten angibt.So erhalten Sie die Bildausrichtung:
Schnell
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 } }
Ziel 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:
Schnell
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Ziel 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];
- Erstellen Sie ein
VisionImage
Objekt mit demCMSampleBufferRef
-Objekt und den Rotationsmetadaten:Schnell
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Ziel c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Drehen Sie das Bild bei Bedarf so, dass seine
- Übergeben Sie dann das Bild an die Methode
detect(in:)
:Schnell
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Ziel c
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. Erhalten Sie Informationen aus Barcodes
Wenn die Barcode-Erkennung erfolgreich ist, 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 seine Grenzkoordinaten im Eingabebild sowie die vom Barcode codierten Rohdaten abrufen. Wenn der Barcode-Detektor außerdem die Art der durch den Barcode codierten Daten ermitteln konnte, können Sie ein Objekt erhalten, das analysierte Daten enthält.Zum Beispiel:
Schnell
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 } }
Ziel 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, befolgen Sie diese Richtlinien, um die besten Bildraten zu erzielen:
Erfassen Sie Eingaben nicht mit der nativen Auflösung der Kamera. Auf einigen Geräten führt die Erfassung von Eingaben mit der nativen Auflösung zu extrem großen Bildern (10+ Megapixel), was zu einer sehr geringen Latenz ohne Vorteile für die Genauigkeit führt. Fordern Sie stattdessen von der Kamera nur die Größe an, die für die Barcode-Erkennung erforderlich ist: in der Regel 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 Bildaufnahme weiter verringern. Beachten Sie jedoch die oben genannten Mindestanforderungen an die Barcodegröße.
- Gasrufe an den Detektor. Wenn ein neues Videobild verfügbar wird, während der Detektor läuft, löschen Sie das Bild.
- Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf dem Eingabebild zu überlagern, rufen Sie zunächst das Ergebnis vom ML Kit ab und rendern Sie dann das Bild und überlagern Sie es in einem einzigen Schritt. Auf diese Weise rendern Sie für jeden Eingaberahmen nur einmal auf der Anzeigeoberfläche. Ein Beispiel finden Sie in den Klassen „previewOverlayView “ und „FIRDetectionOverlayView“ in der Showcase-Beispiel-App.