ML Kit का इस्तेमाल, बारकोड को पहचानने और डिकोड करने के लिए किया जा सकता है.
इसे आज़माएं
- इस एपीआई के इस्तेमाल का उदाहरण देखने के लिए, सैंपल ऐप्लिकेशन पर जाएं.
शुरू करने से पहले
- अपनी Podfile में, इन एमएल किट के पॉड शामिल करें:
pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
- अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद,
.xcworkspace
का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML Kit, Xcode के 12.4 या इसके बाद वाले वर्शन पर काम करती है.
इनपुट इमेज के लिए दिशा-निर्देश
-
ML Kit की मदद से बारकोड को सही तरीके से पढ़ने के लिए, इनपुट इमेज में बारकोड की मदद से बताया जाना चाहिए, ताकि उनमें मौजूद पर्याप्त पिक्सल डेटा मौजूद हो.
पिक्सल के डेटा की ज़रूरी शर्तें, बारकोड के टाइप और उनमें एन्कोड किए गए डेटा की संख्या पर निर्भर करती हैं. ऐसा इसलिए होता है, क्योंकि कई बारकोड अलग-अलग साइज़ वाले पेलोड के साथ काम करते हैं. आम तौर पर, बारकोड की काम की सबसे छोटी यूनिट कम से कम दो पिक्सल चौड़ी होनी चाहिए. साथ ही, दो डाइमेंशन वाले कोड के लिए, इसकी लंबाई 2 पिक्सल होनी चाहिए.
उदाहरण के लिए, EAN-13 बारकोड में बार और स्पेस होते हैं, जिनकी चौड़ाई 1, 2, 3 या 4 यूनिट होती है. इसलिए, EAN-13 बारकोड इमेज में आम तौर पर बार और स्पेस होते हैं, जिनकी चौड़ाई कम से कम 2, 4, 6, और 8 पिक्सल होती है. EAN-13 बारकोड की चौड़ाई कुल 95 यूनिट होती है. इसलिए, बारकोड कम से कम 190 पिक्सल चौड़ा होना चाहिए.
PDF417 जैसे डेंसर फ़ॉर्मैट को, एमएल किट के लिए ज़्यादा पिक्सल डाइमेंशन की ज़रूरत होती है, ताकि उन्हें सही तरीके से पढ़ा जा सके. उदाहरण के लिए, PDF417 कोड की एक पंक्ति में 34 17 यूनिट चौड़े "शब्द" हो सकते हैं. आम तौर पर, इसकी चौड़ाई कम से कम 1156 पिक्सल होनी चाहिए.
-
खराब इमेज फ़ोकस, स्कैनिंग के सटीक होने पर असर डाल सकता है. अगर आपके ऐप्लिकेशन को स्वीकार किए जाने वाले नतीजे नहीं मिल रहे हैं, तो उपयोगकर्ता से इमेज को फिर से कैप्चर करने के लिए कहें.
-
आम तौर पर इस्तेमाल किए जाने वाले ऐप्लिकेशन के लिए, ज़्यादा रिज़ॉल्यूशन वाली इमेज देने का सुझाव दिया जाता है. जैसे 1280x720 या 1920x1080. इससे बारकोड को कैमरे से ज़्यादा दूर से स्कैन किया जा सकता है.
हालांकि, जिन ऐप्लिकेशन में इंतज़ार का समय अहम है वहां कम रिज़ॉल्यूशन में इमेज कैप्चर करके परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. हालांकि, इनपुट इमेज के ज़्यादातर हिस्से में बारकोड का होना ज़रूरी है. रीयल-टाइम में परफ़ॉर्मेंस को बेहतर बनाने के लिए सलाह भी देखें.
1. बारकोड स्कैनर को कॉन्फ़िगर करें
अगर आपको पता है कि आपको कौनसे बारकोड फ़ॉर्मैट पढ़ने चाहिए, तो बारकोड स्कैनर की स्पीड को बेहतर बनाया जा सकता है. इसके लिए, आपको बारकोड स्कैनर को सिर्फ़ उन फ़ॉर्मैट में स्कैन करने के लिए कॉन्फ़िगर करना होगा.उदाहरण के लिए, सिर्फ़ Aztec कोड और क्यूआर कोड स्कैन करने के लिए, एक BarcodeScannerOptions
ऑब्जेक्ट बनाएं, जैसा कि यहां दिए गए उदाहरण में बताया गया है:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
ये फ़ॉर्मैट काम करते हैं:
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- आईटीएफ़
- qrCode
- यूपीए
- यूपीसीई
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
ये फ़ॉर्मैट काम करते हैं:
- कोड-128 (
MLKBarcodeFormatCode128
) - कोड-39 (
MLKBarcodeFormatCode39
) - कोड-93 (
MLKBarcodeFormatCode93
) - कोडाबार (
MLKBarcodeFormatCodaBar
) - डेटा मैट्रिक्स (
MLKBarcodeFormatDataMatrix
) - EAN-13 (
MLKBarcodeFormatEAN13
) - EAN-8 (
MLKBarcodeFormatEAN8
) - आईटीएफ़ (
MLKBarcodeFormatITF
) - क्यूआर कोड (
MLKBarcodeFormatQRCode
) - यूपीसी-ए (
MLKBarcodeFormatUPCA
) - यूपीसी-ई (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - ऐज़्टेक कोड (
MLKBarcodeFormatAztec
)
2. इनपुट इमेज तैयार करना
किसी इमेज में मौजूद बारकोड स्कैन करने के लिए, इमेज कोUIImage
या CMSampleBufferRef
के तौर पर BarcodeScanner
के process()
या results(in:)
तरीके में पास करें:
UIImage
या
CMSampleBuffer
का इस्तेमाल करके, VisionImage
ऑब्जेक्ट बनाएं.
अगर UIImage
का इस्तेमाल किया जाता है, तो यह तरीका अपनाएं:
UIImage
के साथ कोईVisionImage
ऑब्जेक्ट बनाएं. यह पक्का करें कि आपने सही.orientation
डाला है.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
अगर CMSampleBuffer
का इस्तेमाल किया जाता है, तो यह तरीका अपनाएं:
-
CMSampleBuffer
में शामिल इमेज डेटा का ओरिएंटेशन तय करें.इमेज का ओरिएंटेशन पाने के लिए:
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
ऑब्जेक्ट और ओरिएंटेशन का इस्तेमाल करकेVisionImage
ऑब्जेक्ट बनाएं: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 का इंस्टेंस पाएं
BarcodeScanner
का इंस्टेंस पाएं:
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. इमेज प्रोसेस करें
इसके बाद, इमेज कोprocess()
तरीके में पास करें:
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. बारकोड से जानकारी पाएं
अगर बारकोड स्कैन होने की कार्रवाई पूरी हो जाती है, तो स्कैनरBarcode
ऑब्जेक्ट का अरे दिखाता है. हर Barcode
ऑब्जेक्ट, एक बारकोड दिखाता है, जिसकी पहचान इमेज में की गई थी. हर बारकोड के लिए, इनपुट इमेज में इसके बाउंडिंग कोऑर्डिनेट के साथ-साथ बारकोड से एन्कोड किया गया रॉ डेटा देखा जा सकता है. साथ ही, अगर बारकोड स्कैनर बारकोड से एन्कोड किए गए डेटा के प्रकार का पता लगा लेता है, तो आपको एक ऑब्जेक्ट मिल सकता है जिसमें पार्स किया गया डेटा होता है.
उदाहरण के लिए:
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; } }
रीयल-टाइम में परफ़ॉर्मेंस बेहतर करने के लिए सलाह
अगर आपको रीयल-टाइम ऐप्लिकेशन में बारकोड स्कैन करना है, तो सबसे सही फ़्रेमरेट पाने के लिए, इन दिशा-निर्देशों का पालन करें:
-
इनपुट को कैमरे के नेटिव रिज़ॉल्यूशन पर कैप्चर न करें. कुछ डिवाइसों पर, नेटिव रिज़ॉल्यूशन पर इनपुट कैप्चर करने से, बहुत बड़ी (10+ मेगापिक्सल) इमेज जनरेट होती हैं. इस वजह से, इंतज़ार का समय बहुत कम होता है और इन्हें सटीक बनाने का कोई फ़ायदा नहीं होता. इसके बजाय, सिर्फ़ उस कैमरे से साइज़ का अनुरोध करें जो बारकोड स्कैनिंग के लिए ज़रूरी हो. आम तौर पर, यह 2 मेगापिक्सल से ज़्यादा नहीं होता.
हालांकि, नाम वाले कैप्चर सेशन प्रीसेट—
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
वगैरह) का सुझाव नहीं दिया जाता. ऐसा इसलिए, क्योंकि ये कुछ डिवाइसों पर ऐसे रिज़ॉल्यूशन मैप कर सकते हैं जो ज़रूरत के मुताबिक नहीं हैं. इसके बजाय, खास प्रीसेट का इस्तेमाल करें, जैसे किAVCaptureSessionPreset1280x720
.अगर स्कैन करने की स्पीड ज़रूरी है, तो इमेज कैप्चर के रिज़ॉल्यूशन को और कम किया जा सकता है. हालांकि, बारकोड के साइज़ के लिए ऊपर बताई गई ज़रूरी शर्तों को ध्यान में रखें.
अगर वीडियो फ़्रेम की स्ट्रीमिंग के क्रम से बारकोड की पहचान करने की कोशिश की जा रही है, तो हो सकता है कि आइडेंटिफ़ायर, फ़्रेम से फ़्रेम तक अलग-अलग नतीजे दे. आपको एक ही वैल्यू की लगातार सीरीज़ मिलने तक इंतज़ार करना चाहिए, ताकि यह पक्का हो सके कि आपको अच्छा नतीजा मिल रहा है.
Checksum अंक, ITF और CODE-39 के लिए काम नहीं करता.
- वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के
results(in:)
सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से नतीजे सिंक करने के लिए, इस तरीके कोAVCaptureVideoDataOutputSampleBufferDelegate
केcaptureOutput(_, didOutput:from:)
फ़ंक्शन से कॉल करें. डिटेक्टर तक कॉल को थ्रॉटल करने के लिए,AVCaptureVideoDataOutput
केalwaysDiscardsLateVideoFrames
कोtrue
के तौर पर सेट करें. अगर डिटेक्टर के चालू रहने के दौरान, कोई नया वीडियो फ़्रेम उपलब्ध होता है, तो उसे हटा दिया जाएगा. - अगर इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए, डिटेक्टर के आउटपुट का इस्तेमाल किया जाता है, तो सबसे पहले एमएल किट से नतीजा पाएं. इसके बाद, एक ही चरण में इमेज और ओवरले को रेंडर करें. ऐसा करने से, प्रोसेस किए गए हर इनपुट फ़्रेम के लिए, डिसप्ले प्लैटफ़ॉर्म पर सिर्फ़ एक बार रेंडर किया जाता है. उदाहरण के लिए, एमएल किट के क्विकस्टार्ट सैंपल में updatePreviewOverlayViewWithLastFrame देखें.