iOS'te ML Kit ile barkodları tarama

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

Deneyin

Başlamadan önce

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

Resim kuralları girin

  • ML Kit'in barkodları doğru şekilde okuyabilmesi için giriş görüntülerinin yeterli sayıda piksel verisiyle temsil edilen barkodlar içermesi gerekir.

    Birçok barkod değişken boyutlu yükü destekler. Bu nedenle, belirli piksel verisi gereksinimleri hem barkodun türüne hem de içinde kodlanan veri miktarına bağlıdır. Genel olarak, barkodun en küçük anlamlı birimi en az 2 piksel genişliğinde, 2 boyutlu kodlar için 2 piksel yüksekliğinde olmalıdır.

    Örneğin, EAN-13 barkodları 1, 2, 3 veya 4 birim genişliğindeki çubuklardan ve boşluklardan oluşur. Bu nedenle, EAN-13 barkod resminde en az 2, 4, 6 ve 8 piksel genişliğinde çubuklar ve boşluklar bulunur. EAN-13 barkodu toplamda 95 birim genişliğinde olduğundan, barkod en az 190 piksel genişliğinde olmalıdır.

    PDF417 gibi daha yoğun biçimler, ML Kit'in güvenilir bir şekilde okuyabilmesi için daha fazla piksel boyutuna ihtiyaç duyar. Örneğin, bir PDF417 kodu, tek bir satırda en az 1156 piksel genişliğinde olacak şekilde en fazla 34 adet 17 birim genişliğinde "kelime" içerebilir.

  • Kötü odaklama, tarama doğruluğunu etkileyebilir. Uygulamanız kabul edilebilir sonuçlar almıyorsa kullanıcıdan resmi tekrar yakalamasını isteyin.

  • Tipik uygulamalarda, 1280x720 veya 1920x1080 gibi daha yüksek çözünürlüklü bir görüntü kullanılması önerilir. Bu sayede, kameradan daha uzak mesafeden barkodlar taranabilir.

    Bununla birlikte, gecikmenin kritik olduğu uygulamalarda, daha düşük çözünürlükte resimler çekerek performansı artırabilirsiniz. Ancak, giriş görüntüsünün büyük kısmını barkodun içermesi gerekir. Gerçek zamanlı performansı iyileştirmek için ipuçları bölümünü de inceleyin.

1. Barkod tarayıcıyı yapılandırma

Hangi barkod biçimlerini okumayı beklediğinizi biliyorsanız sadece bu biçimleri tarayacak şekilde yapılandırarak barkod tarayıcının hızını artırabilirsiniz.

Örneğin, yalnızca Aztek kodunu ve QR kodlarını taramak için aşağıdaki örnekte gösterildiği gibi bir BarcodeScannerOptions nesnesi oluşturun:

Swift

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

Aşağıdaki biçimler desteklenir:

  • code128
  • code39
  • code93
  • codaBar
  • dataMatrix
  • EAN13
  • EAN8
  • İTŞ
  • 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)
  • Codabar (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ş görüntüsünü hazırlama

Bir görüntüdeki barkodları taramak için resmi BarcodeScanner process() veya results(in:) yöntemine UIImage veya CMSampleBufferRef olarak iletin:

UIImage veya CMSampleBuffer kullanarak VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız aşağıdaki 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 aşağıdaki adımları uygulayın:

  • CMSampleBuffer içinde yer alan resim verilerinin yönünü belirtin.

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

    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 örneği alın

BarcodeScanner örneği 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şle

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 alma

Barkod tarama işlemi başarılı olursa tarayıcı, bir dizi Barcode nesnesi döndürür. Her Barcode nesnesi, resimde algılanan bir barkodu temsil eder. Her barkod için giriş görüntüsündeki sınırlayıcı koordinatlarının yanı sıra barkodla kodlanan ham verileri de alabilirsiniz. Ayrıca, barkod tarayıcı barkod tarafından kodlanan veri türünü belirleyebiliyorsa ayrıştırılmış veriler içeren bir nesne elde edebilirsiniz.

Ö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 en iyi kare hızlarını elde etmek için aşağıdaki yönergeleri uygulayın:

  • Girişleri kameranın yerel çözünürlüğünde yakalamayın. Bazı cihazlarda girişlerin yerel çözünürlükte yakalanması çok büyük (10 megapiksel) görüntüler üretir. Bu da çok düşük gecikmeye neden olur ve doğruluk açısından avantaj sağlamaz. Bunun yerine, kameradan yalnızca barkod tarama için gerekli olan boyutu isteyin. Bu boyut genellikle 2 megapikselden yüksek değildir.

    Ancak, adlandırılmış yakalama oturumu hazır ayarları (AVCaptureSessionPresetDefault, AVCaptureSessionPresetLow, AVCaptureSessionPresetMedium vb.) bazı cihazlarda uygun olmayan çözünürlüklere eşlenebileceğinden önerilmez. Bunun yerine, AVCaptureSessionPreset1280x720 gibi belirli hazır ayarları kullanın.

    Tarama hızı önemliyse görüntü çekim çözünürlüğünü daha da düşürebilirsiniz. Bununla birlikte, yukarıda belirtilen minimum barkod boyutu gereksinimlerini göz önünde bulundurun.

    Bir dizi akışlı video karesinden barkodları tanımaya çalışıyorsanız tanıyıcı, kareden kareye farklı sonuçlar verebilir. İyi bir sonuç döndürdüğünüzden emin olmak için aynı değere sahip ardışık bir seri elde edene kadar beklemeniz gerekir.

    Sağlama hanesi, ITF ve CODE-39 için desteklenmez.

  • Video karelerini işlemek için algılayıcının results(in:) eşzamanlı API'sini kullanın. Belirtilen video karesinden sonuçları eşzamanlı olarak almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) işlevinden çağırın. Çağrıları algılayıcıya kısıtlamak için AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames özelliğini true olarak bırakın. Algılayıcı çalışırken yeni bir video karesi kullanılabilir hale gelirse atlanır.
  • Algılayıcının çıkışını giriş görüntüsünün üzerine grafik yerleştirmek için kullanırsanız önce sonucu ML Kit'ten alın, ardından görüntüyü tek bir adımda oluşturun ve yer paylaşımlı yapın. Bu şekilde, işlenen her giriş çerçevesi için görüntü yüzeyinde yalnızca bir kez görüntü oluşturursunuz. Örneği görmek için ML Kit hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame) örneğine bakın.