iOS पर ML Kit की मदद से बारकोड स्कैन करें

ML Kit का इस्तेमाल, बारकोड को पहचानने और डिकोड करने के लिए किया जा सकता है.

इसे आज़माएं

शुरू करने से पहले

  1. अपनी Podfile में, इन एमएल किट के पॉड शामिल करें:
    pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
    
  2. अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, .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 देखें.