iOS'ta ML Kiti ile Barkodları Tarayın

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

Sen başlamadan önce

  1. Firebase'i uygulamanıza henüz eklemediyseniz başlangıç ​​kılavuzundaki adımları izleyerek bunu yapın.
  2. ML Kit kitaplıklarını Pod dosyanıza ekleyin:
    pod 'Firebase/MLVision'
    pod 'Firebase/MLVisionBarcodeModel'
    
    Projenizin Pod'larını yükledikten veya güncelledikten sonra, Xcode projenizi .xcworkspace kullanarak açtığınızdan emin olun.
  3. Uygulamanızda Firebase'i içe aktarın:

    Süratli

    import Firebase

    Amaç-C

    @import Firebase;

Giriş görseli yönergeleri

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

    Belirli piksel veri gereksinimleri hem barkodun türüne hem de içinde kodlanan veri miktarına bağlıdır (çünkü çoğu barkod değişken uzunluklu bir veri yükünü destekler). Genel olarak barkodun en küçük anlamlı birimi en az 2 piksel genişliğinde (ve 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ğinde çubuklardan ve boşluklardan oluşur; dolayısıyla bir EAN-13 barkod görüntüsünde ideal olarak en az 2, 4, 6 ve 4 birim genişliğinde çubuklar ve boşluklar bulunur. 8 piksel genişliğinde. EAN-13 barkodu toplamda 95 birim genişliğinde olduğundan barkodun en az 190 piksel genişliğinde olması gerekir.

    PDF417 gibi daha yoğun formatların, ML Kit'in bunları güvenilir bir şekilde okuyabilmesi için daha büyük piksel boyutlarına ihtiyacı vardır. Örneğin, bir PDF417 kodu tek bir satırda en fazla 34 adet 17 birim genişliğinde "kelime" içerebilir; bu ideal olarak en az 1156 piksel genişliğinde olacaktır.

  • Zayıf görüntü odağı tarama doğruluğuna zarar verebilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan görüntüyü yeniden yakalamasını istemeyi deneyin.

  • Tipik uygulamalar için, barkodların kameradan daha uzak bir mesafeden algılanabilmesini sağlayan daha yüksek çözünürlüklü bir görüntünün (1280x720 veya 1920x1080 gibi) sağlanması önerilir.

    Ancak gecikmenin kritik olduğu uygulamalarda, görüntüleri daha düşük çözünürlükte yakalayarak ancak barkodun giriş görüntüsünün çoğunluğunu oluşturmasını zorunlu kılarak performansı artırabilirsiniz. Ayrıca bkz . Gerçek zamanlı performansı artırmaya yönelik ipuçları .

1. Barkod dedektörünü yapılandırın

Hangi barkod formatlarını okumayı beklediğinizi biliyorsanız, barkod dedektörünü yalnızca bu formatları algılayacak şekilde yapılandırarak hızını artırabilirsiniz.

Örneğin yalnızca Aztek kodunu ve QR kodlarını algılamak için aşağıdaki örnekte olduğu gibi bir VisionBarcodeDetectorOptions nesnesi oluşturun:

Süratli

let format = VisionBarcodeFormat.all
let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)

Aşağıdaki formatlar desteklenmektedir:

  • Kod128
  • Kod39
  • Kod93
  • CodaBar
  • EAN13
  • EAN8
  • ITF
  • UPCA
  • UPCE
  • QR kod
  • PDF417
  • Aztek
  • Veri matrisi

Amaç-C

FIRVisionBarcodeDetectorOptions *options =
    [[FIRVisionBarcodeDetectorOptions alloc]
     initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];

Aşağıdaki formatlar desteklenmektedir:

  • Kod 128 ( FIRVisionBarcodeFormatCode128 )
  • Kod 39 ( FIRVisionBarcodeFormatCode39 )
  • Kod 93 ( FIRVisionBarcodeFormatCode93 )
  • Codabar ( FIRVisionBarcodeFormatCodaBar )
  • EAN-13 ( FIRVisionBarcodeFormatEAN13 )
  • EAN-8 ( FIRVisionBarcodeFormatEAN8 )
  • ITF ( FIRVisionBarcodeFormatITF )
  • UPC-A ( FIRVisionBarcodeFormatUPCA )
  • UPC-E ( FIRVisionBarcodeFormatUPCE )
  • QR Kodu ( FIRVisionBarcodeFormatQRCode )
  • PDF417 ( FIRVisionBarcodeFormatPDF417 )
  • Aztek ( FIRVisionBarcodeFormatAztec )
  • Veri Matrisi ( FIRVisionBarcodeFormatDataMatrix )

2. Barkod dedektörünü çalıştırın

Bir görüntüdeki barkodları taramak için görüntüyü bir UIImage veya CMSampleBufferRef olarak VisionBarcodeDetector detect(in:) yöntemine iletin:

  1. VisionBarcodeDetector örneğini alın:

    Süratli

    lazy var vision = Vision.vision()
    
    let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
    

    Amaç-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector];
    // Or, to change the default settings:
    // FIRVisionBarcodeDetector *barcodeDetector =
    //     [vision barcodeDetectorWithOptions:options];
    
  2. UIImage veya CMSampleBufferRef kullanarak bir VisionImage nesnesi oluşturun.

    Bir UIImage kullanmak için:

    1. Gerekirse görüntüyü imageOrientation özelliği .up olacak şekilde döndürün.
    2. Doğru şekilde döndürülmüş UIImage kullanarak bir VisionImage nesnesi oluşturun. Herhangi bir döndürme meta verisi belirtmeyin; varsayılan değer olan .topLeft kullanılmalıdır.

      Süratli

      let image = VisionImage(image: uiImage)

      Amaç-C

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

    CMSampleBufferRef kullanmak için:

    1. CMSampleBufferRef arabelleğinde bulunan görüntü verilerinin yönünü belirten bir VisionImageMetadata nesnesi oluşturun.

      Görüntü yönünü elde etmek için:

      Süratli

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

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

      Ardından meta veri nesnesini oluşturun:

      Süratli

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Amaç-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. CMSampleBufferRef nesnesini ve döndürme meta verilerini kullanarak bir VisionImage nesnesi oluşturun:

      Süratli

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

      Amaç-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Ardından görüntüyü detect(in:) yöntemine iletin:

    Süratli

    barcodeDetector.detect(in: visionImage) { features, error in
      guard error == nil, let features = features, !features.isEmpty else {
        // ...
        return
      }
    
      // ...
    }
    

    Amaç-C

    [barcodeDetector detectInImage:image
                        completion:^(NSArray<FIRVisionBarcode *> *barcodes,
                                     NSError *error) {
      if (error != nil) {
        return;
      } else if (barcodes != nil) {
        // Recognized barcodes
        // ...
      }
    }];
    

3. Barkodlardan bilgi alın

Barkod tanıma işlemi başarılı olursa dedektör bir dizi VisionBarcode nesnesi döndürür. Her VisionBarcode nesnesi, görüntüde algılanan bir barkodu temsil eder. Her barkod için, giriş görüntüsündeki sınırlayıcı koordinatların yanı sıra barkod tarafından kodlanan ham verileri de alabilirsiniz. Ayrıca, barkod dedektörü barkod tarafından kodlanan verinin türünü belirleyebilirse ayrıştırılmış verileri içeren bir nesne elde edebilirsiniz.

Örneğin:

Süratli

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

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

Gerçek zamanlı performansı artırmaya yönelik ipuçları

Barkodları gerçek zamanlı bir uygulamada taramak istiyorsanız en iyi kare hızlarına ulaşmak için şu yönergeleri izleyin:

  • Girişi kameranın doğal çözünürlüğünde yakalamayın. Bazı cihazlarda, girdiyi doğal çözünürlükte yakalamak son derece büyük (10+ megapiksel) görüntüler üretir; bu da gecikmenin çok düşük olmasına ve doğruluk açısından hiçbir fayda sağlamamasına neden olur. Bunun yerine, kameradan yalnızca barkod tespiti için gereken boyutu isteyin: genellikle 2 megapikselden fazla değil.

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

    Tarama hızı önemliyse görüntü yakalama çözünürlüğünü daha da düşürebilirsiniz. Ancak yukarıda özetlenen minimum barkod boyutu gerekliliklerini aklınızda bulundurun.

  • Gaz kelebeği dedektöre çağrı yapar. Dedektör çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
  • Giriş görüntüsü üzerine grafikleri yerleştirmek için dedektörün çıkışını kullanıyorsanız, önce ML Kit'ten sonucu alın, ardından tek adımda görüntüyü işleyin ve üst üste koyun. Bunu yaparak, her giriş karesi için ekran yüzeyini yalnızca bir kez görüntüleyebilirsiniz. Örnek için vitrin örnek uygulamasındaki önizlemeOverlayView ve FIRDetectionOverlayView sınıflarına bakın.