Anda dapat menggunakan ML Kit untuk mengenali dan mendekode kode batang.
Sebelum memulai
- Jika belum menambahkan Firebase ke aplikasi, lakukan dengan mengikuti langkah-langkah di panduan memulai.
- Sertakan library ML Kit di Podfile Anda:
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
Setelah menginstal atau mengupdate Pod project, pastikan untuk membuka project Xcode menggunakan.xcworkspace
-nya. - Di aplikasi Anda, impor Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
Pedoman gambar input
-
Agar ML Kit dapat membaca kode batang secara akurat, gambar input harus berisi kode batang yang diwakili oleh data piksel yang memadai.
Persyaratan data piksel tertentu bergantung pada jenis kode batang dan jumlah data yang dienkode di dalamnya (karena sebagian besar kode batang mendukung payload panjang variabel). Secara umum, unit terkecil yang bermakna pada kode batang harus berukuran lebar minimal 2 piksel (dan untuk kode 2 dimensi, tingginya minimal 2 piksel).
Misalnya, kode batang EAN-13 terdiri dari batang dan spasi yang lebarnya 1, 2, 3, atau 4 unit sehingga gambar kode batang EAN-13 idealnya memiliki batang dan spasi yang lebarnya minimal 2, 4, 6, dan 8 piksel. Karena total lebar kode batang EAN-13 adalah 95 unit, kode batang harus berukuran lebar setidaknya 190 piksel.
Format yang lebih padat, seperti PDF417, membutuhkan dimensi piksel yang lebih besar agar ML Kit dapat membacanya dengan baik. Misalnya, kode PDF417 dapat memiliki hingga 34 "kata" dengan lebar unit 17 dalam satu baris, yang idealnya berukuran lebar minimal 1156 piksel.
-
Fokus gambar yang buruk dapat mengurangi akurasi pemindaian. Jika tidak memperoleh hasil yang dapat diterima, coba minta pengguna untuk mengambil ulang gambar.
-
Untuk aplikasi biasa, sebaiknya sediakan gambar dengan resolusi lebih tinggi (misalnya 1280x720 atau 1920x1080), agar kamera dapat mendeteksi kode batang dari jarak yang lebih jauh.
Namun, dalam aplikasi yang sangat mementingkan latensi, Anda dapat meningkatkan performa dengan mengambil gambar pada resolusi yang lebih rendah, tetapi kode batang harus menjadi bagian terbesar dari gambar input. Baca juga Tips untuk meningkatkan performa real-time.
1. Mengonfigurasi detektor kode batang
Jika mengetahui format kode batang yang ingin dibaca, Anda dapat meningkatkan kecepatan detektor kode batang dengan mengonfigurasinya hanya untuk mendeteksi format tersebut.Misalnya untuk hanya mendeteksi kode Aztec dan QR, buat objek VisionBarcodeDetectorOptions
seperti pada contoh berikut:
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Format berikut didukung:
- Code128
- Code39
- Code93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- QRCode
- PDF417
- Aztec
- 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. Menjalankan detektor kode batang
Untuk memindai kode batang dalam gambar, teruskan gambar sebagaiUIImage
atau CMSampleBufferRef
ke metode detect(in:)
VisionBarcodeDetector
:
- Dapatkan instance
VisionBarcodeDetector
:Swift
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];
-
Buat objek
VisionImage
menggunakanUIImage
atauCMSampleBufferRef
.Untuk menggunakan
UIImage
:- Jika perlu, putar gambar sehingga properti
imageOrientation
-nya adalah.up
. - Buat objek
VisionImage
menggunakanUIImage
yang sudah diputar dengan benar. Jangan tentukan metadata rotasi apa pun—yang harus digunakan adalah nilai default, yaitu.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Untuk menggunakan
CMSampleBufferRef
:-
Buat objek
VisionImageMetadata
yang menentukan orientasi data gambar yang terdapat dalam bufferingCMSampleBufferRef
.Untuk mendapatkan orientasi gambar:
Swift
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:
Swift
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];
- Buat objek
VisionImage
menggunakan objekCMSampleBufferRef
dan metadata rotasi:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Jika perlu, putar gambar sehingga properti
-
Lalu, teruskan gambar ke metode
detect(in:)
:Swift
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. Mendapatkan informasi dari kode batang
Jika operasi pengenalan kode batang berhasil, detektor akan menampilkan array objekVisionBarcode
. 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 dienkode oleh
kode batang. Selain itu, jika detektor kode batang dapat menentukan jenis data yang dienkode oleh kode batang, Anda bisa mendapatkan objek yang berisi data yang telah terurai.
Contoh:
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 (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; } }
Tips untuk meningkatkan performa real-time
Jika ingin memindai kode batang dalam aplikasi real-time, ikuti pedoman ini untuk mencapai kecepatan frame terbaik:
-
Jangan ambil input pada resolusi native kamera. Di beberapa perangkat, pengambilan input pada resolusi native menghasilkan gambar yang sangat besar (10+ megapiksel). Ini akan menyebabkan latensi yang sangat buruk tanpa meningkatkan akurasi. Sebagai gantinya, hanya minta ukuran dari kamera yang diperlukan untuk deteksi kode batang: biasanya tidak lebih dari 2 megapiksel.
Namun, sebaiknya jangan gunakan preset sesi pengambilan gambar yang bernama (
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
, dan sebagainya), karena dapat dipetakan ke resolusi yang tidak sesuai pada sebagian perangkat. Sebagai gantinya, gunakan preset tertentu sepertiAVCaptureSessionPreset1280x720
.Jika kecepatan pemindaian penting, Anda dapat menurunkan resolusi pengambilan gambar lebih lanjut. Namun, perhatikan persyaratan ukuran kode batang minimum yang diuraikan di atas.
- Batasi panggilan ke detektor. Jika frame video baru tersedia saat detektor sedang berjalan, hapus frame tersebut.
- Jika Anda menggunakan output detektor untuk menempatkan grafis pada gambar input, pertama-tama dapatkan hasilnya dari ML Kit, lalu render gambar dan tempatkan grafis dalam satu langkah. Dengan demikian, Anda hanya merender ke permukaan tampilan sekali untuk setiap frame input. Lihat class previewOverlayView dan FIRDetectionOverlayView dalam aplikasi contoh showcase untuk mengetahui contohnya.