Barcodes mit ML Kit unter iOS scannen

Mit ML Kit können Sie Barcodes erkennen und decodieren.

Hinweis

  1. Wenn Sie Ihrer App noch nicht Firebase hinzugefügt haben, folgen Sie der im Startleitfaden.
  2. 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 unbedingt Ihren Xcode mithilfe der .xcworkspace zu erstellen.
  3. Importieren Sie Firebase in Ihre App:

    Swift

    import Firebase

    Objective-C

    @import Firebase;

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 Barcode und die darin codierte Datenmenge (da die meisten Barcodes eine Nutzlast mit variabler Länge unterstützen). Im Allgemeinen sollte die kleinste sollte die Einheit des Barcodes mindestens 2 Pixel breit sein (und für 2-dimensionale Codes, 2 Pixel hoch).

    EAN-13-Barcodes bestehen beispielsweise aus Balken und Leerräumen, die 1, 2, 3 oder 4 Einheiten breit sind. Ein EAN-13-Barcodebild sollte also idealerweise Balken und Leerräume mit einer Breite von mindestens 2, 4, 6 und 8 Pixeln haben. 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 Sie keine akzeptable Ergebnisse, versuchen Sie, das Bild erneut aufzunehmen.

  • Für typische Anwendungen empfiehlt es sich, eine höhere Bildauflösung (z. B. 1280 x 720 oder 1920 x 1080), bei dem Barcodes auch bei größerer Entfernung zur Kamera erkennbar sein.

    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-Detektor konfigurieren

Wenn Sie wissen, welche Barcodeformate Sie lesen möchten, können Sie die Geschwindigkeit verbessern des Barcode-Detektors konfigurieren, indem Sie ihn so konfigurieren, dass nur diese Formate erkannt werden.

Um beispielsweise nur Aztec-Code und QR-Codes zu erkennen, erstellen Sie VisionBarcodeDetectorOptions-Objekt wie im folgendes 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)
  • Datenmatrix (FIRVisionBarcodeFormatDataMatrix)

2. Barcode-Detektor ausführen

Um Barcodes in einem Bild zu scannen, übergeben Sie das Bild als UIImage- oder CMSampleBufferRef zu detect(in:) der VisionBarcodeDetector :

  1. Rufen Sie eine VisionBarcodeDetector-Instanz ab:

    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];
  2. Erstellen Sie ein VisionImage-Objekt mithilfe von UIImage oder einem CMSampleBufferRef

    So verwendest du UIImage:

    1. Drehen Sie das Bild gegebenenfalls so, dass es imageOrientation Property ist .up.
    2. Erstellen Sie ein VisionImage-Objekt mithilfe der korrekt gedrehten UIImage. Geben Sie keine Rotationsmetadaten an. Dies ist die Standardeinstellung. Wert .topLeft muss verwendet werden.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    So verwenden Sie ein CMSampleBufferRef:

    1. Erstellen Sie ein VisionImageMetadata-Objekt, das die Ausrichtung der Bilddaten im CMSampleBufferRef-Zwischenspeicher.

      So ermitteln Sie die Bildausrichtung:

      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];
    2. Erstellen Sie ein VisionImage-Objekt mithilfe der CMSampleBufferRef-Objekt und die Rotationsmetadaten:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Übergeben Sie dann das Bild an die Methode 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. Informationen aus Barcodes abrufen

Wenn die Barcodeerkennung erfolgreich ist, gibt der Detektor ein Array von VisionBarcode-Objekte. Jedes VisionBarcode-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-Detektor den Datentyp ermitteln konnte, 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 (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 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 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. Fordern Sie stattdessen nur die erforderliche Größe von der Kamera an. zur Barcodeerkennung: in der Regel nicht mehr als 2 Megapixel.

    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 wie AVCaptureSessionPreset1280x720.

    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.

  • 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 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 für jeden Eingabe-Frame nur einmal. Weitere Informationen finden Sie unter previewOverlayView. und FIRDetectionOverlayView in der Showcase-Beispiel-App als Beispiel.