iOS'te ML Kit ile barkodları tarama

Barkodları tanımak ve kodunu çözmek için ML Kit'i kullanabilirsiniz.

Deneyin

Başlamadan önce

  1. Aşağıdaki ML Kit kapsüllerini Podfile'ınıza ekleyin:
    pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
    
  2. Projenizin kapsüllerini yükledikten veya güncelledikten sonra .xcworkspace ML Kit, Xcode 12.4 veya sonraki sürümlerde desteklenir.

Giriş resmi kuralları

  • ML Kit'in barkodları doğru okuyabilmesi için giriş resimlerinde yeterli piksel verisiyle temsil edilen barkodlar.

    Belirli piksel verisi gereksinimleri hem çok sayıda barkod olduğundan, barkodla birlikte kodlanan veri miktarı taşımayı destekler. Genellikle anlamlı olan en küçük barkodun birimi en az 2 piksel genişliğinde olmalı ve 2 piksel yüksekliğinde 2 boyutlu kodlar.

    Örneğin, EAN-13 barkodları çubuklar ile boşluklardan oluşur. Bu boşlukların sayısı 1, 2, 3 veya 4 birim genişliğinde olduğundan EAN-13 barkod görüntüsünde ideal olarak çubuklar ve en az 2, 4, 6 ve 8 piksel genişliğinde boşluklar. Çünkü EAN-13 barkod toplam 95 birim genişliğinde, barkod en az 190 olmalıdır piksel genişliğinde.

    PDF417 gibi daha yoğun biçimler için güvenli okumasını sağlayın. Örneğin, bir PDF417 kodunda en fazla 34 17 birim genişliğinde "kelimeler" bir satır olacak şekilde ekleyebilirsiniz. Bu, tercihen 1156 piksel genişliğinde.

  • Kötü bir resim odağı, tarama doğruluğunu etkileyebilir. Uygulamanız kabul edilebilir sonuçlar almak için kullanıcıdan resmi yeniden çekmesini isteyin.

  • Tipik uygulamalarda, daha yüksek bir Barkod üreten, 1280x720 veya 1920x1080 gibi çözünürlüklü bir resim uzaktan taranabilir niteliktedir.

    Ancak gecikmenin kritik olduğu uygulamalarda daha iyi daha düşük çözünürlükte çekerek daha iyi performans giriş resminin büyük kısmını barkod oluşturur. Şunlara da bakabilirsiniz: Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları.

1. Barkod tarayıcıyı yapılandırın

Hangi barkod biçimlerini okumayı beklediğinizi bilirseniz hızı artırabilirsiniz tarayıcıyı yalnızca bu biçimleri tarayacak şekilde yapılandırabilirsiniz.

Örneğin, sadece Aztek kodunu ve QR kodlarını taramak için bir Şu anki BarcodeScannerOptions nesnesi şu örneği inceleyin:

Swift

let format = .all
let barcodeOptions = BarcodeScannerOptions(formats: format)
  

Aşağıdaki biçimler desteklenir:

  • code128
  • code39
  • code93
  • codaBar
  • dataMatrix
  • EAN13
  • EAN8
  • ITF
  • qrCode
  • UPCA
  • UPCE
  • PDF417
  • Aztec

Objective-C

MLKBarcodeScannerOptions *options =
  [[MLKBarcodeScannerOptions alloc]
   initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];

Aşağıdaki biçimler desteklenir:

  • Kod-128 (MLKBarcodeFormatCode128)
  • Kod-39 (MLKBarcodeFormatCode39)
  • Kod-93 (MLKBarcodeFormatCode93)
  • Kodabar (MLKBarcodeFormatCodaBar)
  • Veri Matrisi (MLKBarcodeFormatDataMatrix)
  • EAN-13 (MLKBarcodeFormatEAN13)
  • EAN-8 (MLKBarcodeFormatEAN8)
  • ITF (MLKBarcodeFormatITF)
  • QR Kodu (MLKBarcodeFormatQRCode)
  • UPC-A (MLKBarcodeFormatUPCA)
  • UPC-E (MLKBarcodeFormatUPCE)
  • PDF-417 (MLKBarcodeFormatPDF417)
  • Aztek Kodu (MLKBarcodeFormatAztec)

2. Giriş resmini hazırlama

Bir resimdeki barkodları taramak için resmi UIImage veya BarcodeScanner adlı kullanıcının process() veya results(in:) yönüne giden CMSampleBufferRef treni yöntem:

Bir VisionImage nesnesi oluşturmak için UIImage veya CMSampleBuffer.

UIImage kullanıyorsanız şu adımları uygulayın:

  • UIImage ile bir VisionImage nesnesi oluşturun. Doğru .orientation değerini belirttiğinizden emin olun.

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

CMSampleBuffer kullanıyorsanız şu adımları uygulayın:

  • Belgenin CMSampleBuffer

    Resmin yönünü öğrenmek için:

    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;
      }
    }
          
  • Şu komutu kullanarak bir VisionImage nesnesi oluşturun: CMSampleBuffer nesne ve yön:

    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'ın bir örneğini alın

BarcodeScanner öğesinin bir örneğini alın:

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. Resmi işleyin

Ardından resmi process() yöntemine iletin:

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. Barkodlardan bilgi al

Barkod tarama işlemi başarılı olursa tarayıcı bir dizi Barcode nesne algılandı. Her Barcode nesnesi bir barkodu kullanabilirsiniz. Her barkod için giriş görüntüsündeki sınırlayıcı koordinatların yanı sıra barkodu görürsünüz. Ayrıca, barkod tarayıcısı veri türünü tarafından kodlanırsa ayrıştırılmış veri içeren bir nesne alabilirsiniz.

Örneğin:

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;
   }
 }

Gerçek zamanlı performansı iyileştirmeye yönelik ipuçları

Barkodları gerçek zamanlı bir uygulamada taramak istiyorsanız aşağıdaki talimatları uygulayın:

  • Girişleri kameranın orijinal çözünürlüğünde yakalamayın. Bazı cihazlarda yerel çözünürlükte giriş yakalamak çok büyük (10+ megapiksel) resimler, hiçbir yararı olmadan çok düşük gecikme emin olun. Bunun yerine, kameradan yalnızca gerekli boyutu isteyin (genellikle 2 megapikselden yüksek değildir).

    Adlandırılmış yakalama oturumu hazır ayarları: AVCaptureSessionPresetDefault, AVCaptureSessionPresetLow AVCaptureSessionPresetMedium, gibi) kullanılması önerilmez. Bunun nedeni, bazı cihazlarda uygun olmayan çözünürlükler sunar. Bunun yerine, kullandığınız hazır ayarları kullanarak AVCaptureSessionPreset1280x720 gibi.

    Tarama hızı önemliyse yakalanan görüntüyü daha da düşürebilirsiniz belirler. Ancak barkodla ilgili minimum boyut gereksinimlerini de göz önünde bulundurun. kontrol edin.

    Bir akış dizisindeki barkodları tanımaya çalışıyorsanız tanıyıcı, kareden kareye veya kareye çerçeve. Aynı sayıda ardışık düzeni elde edene kadar değerini belirlemektir.

    Denetim Toplamı basamağı, ITF ve CODE-39 için desteklenmiyor.

  • Video karelerini işlemek için algılayıcının results(in:) eşzamanlı API'sini kullanın. Telefonla arama AVCaptureVideoDataOutputSampleBufferDelegate İlgili videodan eşzamanlı olarak sonuç almak için captureOutput(_, didOutput:from:) işlevi çerçeve. sakla AVCaptureVideoDataOutput adlı kullanıcının Algılayıcıya yapılan çağrıları kısmak için true olarak alwaysDiscardsLateVideoFrames. Yeni bir Video karesi, algılayıcı çalışırken kullanılabilir hale gelir ve algılanmaz.
  • Algılayıcının çıkışını, üzerine grafik yerleştirmek için giriş görüntüsünü kullanın, önce ML Kit'ten sonucu alın ve ardından görüntüyü oluşturun tek bir adımda yapabilirsiniz. Bu şekilde, öğeleri ekran yüzeyinde işlenen her giriş çerçevesi için yalnızca bir kez. Bkz. updatePreviewOverlayViewWithLastFrame ML Kit hızlı başlangıç örneğine göz atın.