iOS पर ML Kit के साथ बारकोड स्कैन करना

आप बारकोड पहचानने और डिकोड करने के लिए ML किट का इस्तेमाल कर सकते हैं.

इसे आज़माएं

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

  1. अपनी Podfile में ये ML किट पॉड शामिल करें:
    pod 'GoogleMLKit/BarcodeScanning', '3.2.0'
    
  2. अपने प्रोजेक्ट के पॉड इंस्टॉल करने या अपडेट करने के बाद, अपने .xcworkspaceकोड का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML किट, Xcode के 12.4 या इसके बाद के वर्शन पर काम करती है.

इनपुट इमेज के दिशा-निर्देश

  • मशीन लर्निंग (ML) किट में मौजूद बारकोड को सही तरीके से पढ़ने के लिए, इनपुट इमेज में ऐसे बारकोड होने चाहिए जिन्हें पिक्सल डेटा की मदद से दिखाया गया हो.

    पिक्सल से जुड़ी ज़रूरी शर्तें, बारकोड के टाइप और उसमें एन्कोड किए गए डेटा, दोनों के आधार पर तय की जाती हैं. ऐसा इसलिए होता है, क्योंकि कई बारकोड में वैरिएबल साइज़ पेलोड होता है. आम तौर पर, बारकोड की सबसे छोटी और अहम जानकारी वाली यूनिट कम से कम 2 पिक्सल की होनी चाहिए. साथ ही, दो डाइमेंशन वाले कोड और दो पिक्सल लंबे होने चाहिए.

    उदाहरण के लिए, EAN-13 बारकोड में ऐसे बार और स्पेस होते हैं जो 1, 2, 3 या 4 यूनिट वाले होते हैं. इसलिए, EAN-13 बारकोड इमेज में कम से कम 2, 4, 6, और 8 पिक्सल की चौड़ाई वाले बार और स्पेस होते हैं. ईएएन-13 बारकोड की लंबाई 95 यूनिट होती है. इसलिए, बारकोड कम से कम 190 पिक्सल का होना चाहिए.

    डेंसर के फ़ॉर्मैट, जैसे कि PDF417 का इस्तेमाल करने से, पिक्सल पिक्सल को बेहतर तरीके से पढ़ने में मदद मिलती है. उदाहरण के लिए, PDF417 कोड में एक ही पंक्ति में ज़्यादा से ज़्यादा 34 17 यूनिट वाली चौड़ी "शब्द" हो सकती है जो आम तौर पर कम से कम 1156 पिक्सल चौड़ी होनी चाहिए.

  • इमेज का फ़ोकस ठीक न होने से, स्कैन करने की प्रोसेस पर असर पड़ सकता है. अगर आपके ऐप्लिकेशन को स्वीकार किए जाने वाले नतीजे नहीं मिल रहे हैं, तो उपयोगकर्ता से इमेज को फिर से देखने के लिए कहें.

  • आम तौर पर इस्तेमाल किए जाने वाले ऐप्लिकेशन के लिए, ज़्यादा रिज़ॉल्यूशन वाली इमेज देने का सुझाव दिया जाता है, जैसे कि 1280x720 या 1920x1080. ऐसी इमेज में बारकोड को कैमरे से दूर से स्कैन किया जा सकता है.

    हालांकि, जिन ऐप्लिकेशन में इंतज़ार का समय बहुत कम होता है उनमें इमेज को कम रिज़ॉल्यूशन में कैप्चर करके, परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. हालांकि, इनपुट के ज़्यादातर हिस्से में बारकोड शामिल होना चाहिए. रीयल-टाइम परफ़ॉर्मेंस को बेहतर बनाने के लिए सलाह भी देखें.

1. बारकोड स्कैनर कॉन्फ़िगर करें

अगर आपको पता है कि आपको किस बारकोड फ़ॉर्मैट को पढ़ना है, तो आप बारकोड स्कैनर को सिर्फ़ उन फ़ॉर्मैट को स्कैन करने के लिए कॉन्फ़िगर करके, उसकी स्पीड को बेहतर बना सकते हैं.

उदाहरण के लिए, सिर्फ़ ऐज़टेक कोड और क्यूआर कोड स्कैन करने के लिए, BarcodeScannerOptions ऑब्जेक्ट बनाएं, जैसा कि इस उदाहरण में दिया गया है:

Swift

let format = .all
let barcodeOptions = BarcodeScannerOptions(formats: format)
  

इस फ़ॉर्मैट का इस्तेमाल किया जा सकता है:

  • कोड128
  • कोड39
  • कोड93
  • codaBar
  • डेटा मैट्रिक्स
  • EAN13
  • EAN8
  • आईटीएफ़
  • क्यूआर कोड
  • यूपीसीए
  • यूपीसी
  • PDF417
  • Aztec

Objective-C

MLKBarcodeScannerOptions *options =
  [[MLKBarcodeScannerOptions alloc]
   initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];

इस फ़ॉर्मैट का इस्तेमाल किया जा सकता है:

  • कोड-128 (MLKBarcodeFormatCode128)
  • कोड-39 (MLKBarcodeFormatCode39)
  • कोड-93 (MLKBarcodeFormatCode93)
  • कोडाबार (MLKBarcodeFormatCodaBar)
  • डेटा मैट्रिक्स (MLKBarcodeFormatDataMatrix)
  • EAN-13 (MLKBarcodeFormatEAN13)
  • ईएएन-8 (MLKBarcodeFormatEAN8)
  • आईटीएफ़ (MLKBarcodeFormatITF)
  • क्यूआर कोड (MLKBarcodeFormatQRCode)
  • यूपीसी-ए (MLKBarcodeFormatUPCA)
  • यूपीसी-ई (MLKBarcodeFormatUPCE)
  • PDF-417 (MLKBarcodeFormatPDF417)
  • ऐज़टेक कोड (MLKBarcodeFormatAztec)

2. इनपुट इमेज तैयार करें

बारकोड को स्कैन करने के लिए, BarcodeScanner या process() वाले तरीके का इस्तेमाल करके इमेज को UIImage या CMSampleBufferRef के तौर पर पास करें:

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+ मेगापिक्सल) इमेज बनती हैं. इस वजह से, इंतज़ार का समय बहुत कम होता है और सटीक होने का कोई फ़ायदा नहीं होता. इसके बजाय, बारकोड के लिए ज़रूरी कैमरे से ही साइज़ का अनुरोध करें. आम तौर पर, फ़ाइल का साइज़ दो मेगापिक्सल से ज़्यादा नहीं होना चाहिए.

    नाम वाले कैप्चर प्रीसेट—AVCaptureSessionPresetDefault, AVCaptureSessionPresetLow, AVCaptureSessionPresetMedium, वगैरह) का सुझाव नहीं दिया जाता, क्योंकि वे कुछ डिवाइसों पर सही रिज़ॉल्यूशन पर मैप हो सकते हैं. इसके बजाय, खास प्रीसेट, जैसे कि AVCaptureSessionPreset1280x720 का इस्तेमाल करें.

    अगर स्कैनिंग की गति अहम है, तो इमेज कैप्चर करने के रिज़ॉल्यूशन को कम किया जा सकता है. हालांकि, ध्यान रखें कि ऊपर बताए गए बारकोड के साइज़ की शर्तें कम से कम हों.

    अगर वीडियो स्ट्रीम करने वाले क्रम में मौजूद बारकोड को पहचानने की कोशिश की जा रही है, तो हो सकता है कि पहचानकर्ता फ़्रेम-टू-फ़्रेम पर अलग-अलग नतीजे दिखाए. आपको अच्छे नतीजे देने के लिए, एक ही वैल्यू की लगातार सीरीज़ मिलने तक इंतज़ार करना चाहिए.

    Checksum अंक का इस्तेमाल ITF और CODE-39 के लिए नहीं किया जा सकता.

  • वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के results(in:) सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से सिंक्रोनस रूप से परिणाम पाने के लिए AVCaptureVideoDataOutputSampleBufferDelegate के captureOutput(_, didOutput:from:) फ़ंक्शन से इस विधि को कॉल करें. AVCaptureVideoDataOutput की alwaysDiscardsLateVideoFrames को true के तौर पर रखें, ताकि डिटेक्टर को कॉल थ्रॉटल किए जा सकें. अगर डिटेक्टर चलने के दौरान नया वीडियो फ़्रेम उपलब्ध हो जाता है, तो उसे छोड़ दिया जाएगा.
  • अगर आप इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए डिटेक्टर के आउटपुट का इस्तेमाल करते हैं, तो पहले ML किट से नतीजा पाएं. इसके बाद, इमेज और ओवरले को एक ही चरण में रेंडर करें. ऐसा करके, आप हर प्रोसेस किए गए इनपुट फ़्रेम के लिए डिसप्ले को सिर्फ़ एक बार रेंडर करते हैं. उदाहरण के लिए, ML किट क्विकस्टार्ट सैंपल में updatepreviewOverlayViewWithLastFrame देखें.