Barcodes mit ML Kit für iOS scannen

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

  1. Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei ein:
    pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
    
  2. 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, 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 einzigen 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 als UIImage- 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 der UIImage. 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 der CMSampleBuffer-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 eine BarcodeScanner-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 Methode process():

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 Array Barcode-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 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.

    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 dem AVCaptureVideoDataOutputSampleBufferDelegate <ph type="x-smartling-placeholder"></ph> captureOutput(_, didOutput:from:)-Funktion, um synchron Ergebnisse aus dem angegebenen Video abzurufen Frame. beibehalten von AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames als true, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer verfügbar wird, während der Detektor läuft, 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.