Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Memindai Kode Batang dengan ML Kit di iOS

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Anda dapat menggunakan ML Kit untuk mengenali dan mendekode kode batang.

Sebelum kamu memulai

  1. Jika Anda belum menambahkan Firebase ke aplikasi Anda, lakukan dengan mengikuti langkah-langkah di panduan memulai .
  2. Sertakan library ML Kit di Podfile Anda: l10n
    pod 'Firebase/MLVision'
    pod 'Firebase/MLVisionBarcodeModel'
    
    Setelah Anda menginstal atau memperbarui Pod proyek Anda, pastikan untuk membuka proyek Xcode Anda menggunakan .xcworkspace -nya.
  3. Di aplikasi Anda, impor Firebase:

    Cepat

    import Firebase

    Objective-C

    @import Firebase;

Pedoman gambar masukan

  • Agar ML Kit dapat membaca kode batang secara akurat, gambar masukan harus berisi kode batang yang diwakili oleh data piksel yang memadai.

    Persyaratan data piksel tertentu bergantung pada jenis kode batang dan jumlah data yang dikodekan di dalamnya (karena sebagian besar kode batang mendukung muatan panjang variabel). Secara umum, unit terkecil dari kode batang harus memiliki lebar minimal 2 piksel (dan untuk kode 2 dimensi, tingginya 2 piksel).

    Misalnya, barcode EAN-13 terdiri dari batang dan spasi yang lebarnya 1, 2, 3, atau 4 satuan, sehingga gambar barcode EAN-13 idealnya memiliki batang dan spasi yang minimal 2, 4, 6, dan lebar 8 piksel. Karena barcode EAN-13 memiliki lebar total 95 unit, lebar barcode minimal harus 190 piksel.

    Format yang lebih padat, seperti PDF417, memerlukan dimensi piksel yang lebih besar agar ML Kit dapat membacanya dengan andal. Misalnya, kode PDF417 dapat memiliki hingga 34 "kata" dengan lebar 17 unit dalam satu baris, yang idealnya memiliki lebar setidaknya 1156 piksel.

  • Fokus gambar yang buruk dapat merusak akurasi pemindaian. Jika Anda tidak mendapatkan hasil yang dapat diterima, coba minta pengguna untuk mengambil kembali gambar tersebut.

  • Untuk aplikasi umum, disarankan untuk menyediakan gambar dengan resolusi lebih tinggi (seperti 1280x720 atau 1920x1080), yang membuat kode batang dapat dideteksi dari jarak yang lebih jauh dari kamera.

    Namun, dalam aplikasi di mana latensi sangat penting, Anda dapat meningkatkan kinerja dengan mengambil gambar pada resolusi yang lebih rendah, tetapi mengharuskan kode batang menjadi mayoritas gambar input. Lihat juga Kiat untuk meningkatkan kinerja waktu nyata .

1. Konfigurasikan detektor kode batang

Jika Anda mengetahui format kode batang mana yang ingin Anda baca, Anda dapat meningkatkan kecepatan detektor kode batang dengan mengonfigurasinya agar hanya mendeteksi format tersebut.

Misalnya, untuk mendeteksi hanya kode Aztec dan kode QR, buat objek VisionBarcodeDetectorOptions seperti dalam contoh berikut:

Cepat

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

Format berikut didukung:

  • Kode128
  • Kode39
  • Kode93
  • CodaBar
  • EAN13
  • EAN8
  • ITF
  • UCA
  • UPCE
  • Kode QR
  • PDF417
  • Aztek
  • DataMatrix

Objective-C

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

Format berikut didukung:

  • Kode 128 ( FIRVisionBarcodeFormatCode128 )
  • Kode 39 ( FIRVisionBarcodeFormatCode39 )
  • Kode 93 ( FIRVisionBarcodeFormatCode93 )
  • Codabar ( FIRVisionBarcodeFormatCodaBar )
  • EAN-13 ( FIRVisionBarcodeFormatEAN13 )
  • EAN-8 ( FIRVisionBarcodeFormatEAN8 )
  • ITF ( FIRVisionBarcodeFormatITF )
  • UPC-A ( FIRVisionBarcodeFormatUPCA )
  • UPC-E ( FIRVisionBarcodeFormatUPCE )
  • Kode QR ( FIRVisionBarcodeFormatQRCode )
  • PDF417 ( FIRVisionBarcodeFormatPDF417 )
  • Aztec ( FIRVisionBarcodeFormatAztec )
  • Matriks Data ( FIRVisionBarcodeFormatDataMatrix )

2. Jalankan detektor kode batang

Untuk memindai kode batang dalam gambar, teruskan gambar sebagai UIImage atau CMSampleBufferRef ke metode detect(in:) VisionBarcodeDetector :

  1. Dapatkan instance VisionBarcodeDetector :

    Cepat

    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. Buat objek VisionImage menggunakan UIImage atau CMSampleBufferRef .

    Untuk menggunakan UIImage :

    1. Jika perlu, putar gambar sehingga properti imageOrientation -nya menjadi .up .
    2. Buat objek VisionImage menggunakan UIImage yang diputar dengan benar. Jangan tentukan metadata rotasi apa pun—nilai default, .topLeft , harus digunakan.

      Cepat

      let image = VisionImage(image: uiImage)

      Objective-C

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

    Untuk menggunakan CMSampleBufferRef :

    1. Buat objek VisionImageMetadata yang menentukan orientasi data gambar yang terdapat dalam buffer CMSampleBufferRef .

      Untuk mendapatkan orientasi gambar:

      Cepat

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

      Kemudian, buat objek metadata:

      Cepat

      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. Buat objek VisionImage menggunakan objek CMSampleBufferRef dan metadata rotasi:

      Cepat

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Kemudian, berikan gambar ke metode detect(in:) :

    Cepat

    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. Dapatkan informasi dari barcode

Jika operasi pengenalan kode batang berhasil, detektor mengembalikan larik objek VisionBarcode . Setiap objek VisionBarcode mewakili kode batang yang terdeteksi dalam gambar. Untuk setiap kode batang, Anda bisa mendapatkan koordinat pembatasnya di gambar input, serta data mentah yang dikodekan oleh kode batang. Juga, jika detektor kode batang dapat menentukan jenis data yang dikodekan oleh kode batang, Anda bisa mendapatkan objek yang berisi data yang diuraikan.

Sebagai contoh:

Cepat

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

Kiat untuk meningkatkan kinerja waktu nyata

Jika Anda ingin memindai kode batang dalam aplikasi waktu nyata, ikuti panduan ini untuk mencapai frekuensi gambar terbaik:

  • Jangan ambil input pada resolusi asli kamera. Pada beberapa perangkat, menangkap input pada resolusi asli menghasilkan gambar yang sangat besar (10+ megapiksel), yang menghasilkan latensi yang sangat buruk tanpa manfaat untuk akurasi. Sebagai gantinya, hanya minta ukuran dari kamera yang diperlukan untuk deteksi kode batang: biasanya tidak lebih dari 2 megapiksel.

    Preset sesi pengambilan bernama— AVCaptureSessionPresetDefault , AVCaptureSessionPresetLow , AVCaptureSessionPresetMedium , dan seterusnya)—tidak disarankan, karena dapat memetakan ke resolusi yang tidak sesuai pada beberapa perangkat. Sebagai gantinya, gunakan preset spesifik seperti AVCaptureSessionPreset1280x720 .

    Jika kecepatan pemindaian penting, Anda dapat lebih jauh menurunkan resolusi pengambilan gambar. Namun, ingatlah persyaratan ukuran kode batang minimum yang diuraikan di atas.

  • Panggilan throttle ke detektor. Jika bingkai video baru tersedia saat detektor sedang berjalan, jatuhkan bingkai.
  • Jika Anda menggunakan output detektor untuk melapisi grafik pada gambar input, pertama-tama dapatkan hasilnya dari ML Kit, lalu render gambar dan overlay dalam satu langkah. Dengan melakukannya, Anda merender ke permukaan tampilan hanya sekali untuk setiap bingkai input. Lihat kelas previewOverlayView dan FIRDetectionOverlayView di aplikasi contoh etalase sebagai contoh.