iOS এ ML কিট দিয়ে বারকোড স্ক্যান করুন

আপনি বারকোড চিনতে এবং ডিকোড করতে ML কিট ব্যবহার করতে পারেন।

চেষ্টা করে দেখুন

আপনি শুরু করার আগে

  1. আপনার পডফাইলে নিম্নলিখিত এমএল কিট পডগুলি অন্তর্ভুক্ত করুন:
    pod 'GoogleMLKit/BarcodeScanning', '15.5.0'
    
  2. আপনি আপনার প্রোজেক্টের পড ইনস্টল বা আপডেট করার পরে, এটির .xcworkspace ব্যবহার করে আপনার Xcode প্রকল্পটি খুলুন। ML Kit Xcode সংস্করণ 12.4 বা তার বেশিতে সমর্থিত।

ইনপুট ইমেজ নির্দেশিকা

  • এমএল কিট সঠিকভাবে বারকোড পড়ার জন্য, ইনপুট চিত্রগুলিতে অবশ্যই বারকোড থাকতে হবে যা পর্যাপ্ত পিক্সেল ডেটা দ্বারা উপস্থাপিত হয়।

    নির্দিষ্ট পিক্সেল ডেটা প্রয়োজনীয়তা বারকোডের ধরন এবং এতে এনকোড করা ডেটার পরিমাণ উভয়ের উপর নির্ভর করে, যেহেতু অনেক বারকোড পরিবর্তনশীল আকারের পেলোড সমর্থন করে। সাধারণভাবে, বারকোডের ক্ষুদ্রতম অর্থপূর্ণ এককটি কমপক্ষে 2 পিক্সেল প্রশস্ত হওয়া উচিত এবং 2-মাত্রিক কোডগুলির জন্য, 2 পিক্সেল লম্বা হওয়া উচিত৷

    উদাহরণস্বরূপ, EAN-13 বারকোডগুলি 1, 2, 3, বা 4 ইউনিট প্রশস্ত বার এবং স্পেস দিয়ে তৈরি, তাই একটি EAN-13 বারকোড ছবিতে আদর্শভাবে বার এবং স্পেস রয়েছে যা কমপক্ষে 2, 4, 6, এবং 8 পিক্সেল চওড়া। যেহেতু একটি EAN-13 বারকোড মোট 95 ইউনিট চওড়া, বারকোডটি কমপক্ষে 190 পিক্সেল প্রশস্ত হওয়া উচিত।

    ঘন বিন্যাস, যেমন PDF417, ML Kit এর নির্ভরযোগ্যভাবে পড়ার জন্য তাদের পিক্সেল মাত্রার প্রয়োজন। উদাহরণস্বরূপ, একটি PDF417 কোডে একক সারিতে 34 17-ইউনিট চওড়া "শব্দ" থাকতে পারে, যা আদর্শভাবে কমপক্ষে 1156 পিক্সেল চওড়া হবে।

  • খারাপ ইমেজ ফোকাস স্ক্যানিং নির্ভুলতা প্রভাবিত করতে পারে। আপনার অ্যাপ গ্রহণযোগ্য ফলাফল না পেলে, ব্যবহারকারীকে ছবিটি পুনরায় ক্যাপচার করতে বলুন।

  • সাধারণ অ্যাপ্লিকেশানগুলির জন্য, এটি একটি উচ্চ রেজোলিউশনের চিত্র প্রদান করার পরামর্শ দেওয়া হয়, যেমন 1280x720 বা 1920x1080, যা বারকোডগুলিকে ক্যামেরা থেকে অনেক দূরে থেকে স্ক্যানযোগ্য করে তোলে৷

    যাইহোক, অ্যাপ্লিকেশানগুলিতে যেখানে লেটেন্সি গুরুত্বপূর্ণ, আপনি কম রেজোলিউশনে চিত্রগুলি ক্যাপচার করে কার্যক্ষমতা উন্নত করতে পারেন, তবে বারকোডটি ইনপুট চিত্রের বেশিরভাগ অংশ তৈরি করতে হবে৷ এছাড়াও রিয়েল-টাইম কর্মক্ষমতা উন্নত করার টিপস দেখুন।

1. বারকোড স্ক্যানার কনফিগার করুন

আপনি যদি জানেন যে কোন বারকোড ফর্ম্যাটগুলি আপনি পড়তে আশা করেন, আপনি বারকোড স্ক্যানারটিকে শুধুমাত্র সেই ফর্ম্যাটগুলিকে স্ক্যান করার জন্য কনফিগার করে এর গতি উন্নত করতে পারেন৷

উদাহরণস্বরূপ, শুধুমাত্র Aztec কোড এবং QR কোড স্ক্যান করতে, নিম্নলিখিত উদাহরণের মত একটি BarcodeScannerOptions অবজেক্ট তৈরি করুন:

সুইফট

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

নিম্নলিখিত বিন্যাস সমর্থিত:

  • কোড128
  • কোড39
  • কোড93
  • কোডাবার
  • ডেটাম্যাট্রিক্স
  • EAN13
  • EAN8
  • আইটিএফ
  • qrCode
  • ইউপিসিএ
  • ইউপিসিই
  • PDF417
  • অ্যাজটেক

উদ্দেশ্য-C

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

নিম্নলিখিত বিন্যাস সমর্থিত:

  • কোড-128 ( MLKBarcodeFormatCode128 )
  • কোড-৩৯ ( MLKBarcodeFormatCode39 )
  • কোড-93 ( MLKBarcodeFormatCode93 )
  • কোডবার ( MLKBarcodeFormatCodaBar )
  • ডেটা ম্যাট্রিক্স ( MLKBarcodeFormatDataMatrix )
  • EAN-13 ( MLKBarcodeFormatEAN13 )
  • EAN-8 ( MLKBarcodeFormatEAN8 )
  • ITF ( MLKBarcodeFormatITF )
  • কিউআর কোড ( MLKBarcodeFormatQRCode )
  • UPC-A ( MLKBarcodeFormatUPCA )
  • UPC-E ( MLKBarcodeFormatUPCE )
  • PDF-417 ( MLKBarcodeFormatPDF417 )
  • অ্যাজটেক কোড ( MLKBarcodeFormatAztec )

2. ইনপুট ইমেজ প্রস্তুত করুন

একটি ছবিতে বারকোড স্ক্যান করতে, ছবিটিকে UIImage বা CMSampleBufferRef হিসাবে BarcodeScanner process() বা results(in:) পদ্ধতিতে পাস করুন:

একটি UIImage বা একটি CMSampleBuffer ব্যবহার করে একটি VisionImage অবজেক্ট তৈরি করুন।

আপনি একটি UIImage ব্যবহার করলে, এই পদক্ষেপগুলি অনুসরণ করুন:

  • UIImage দিয়ে একটি VisionImage অবজেক্ট তৈরি করুন। সঠিক .orientation উল্লেখ করতে ভুলবেন না।

    সুইফট

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    উদ্দেশ্য-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

আপনি যদি একটি CMSampleBuffer ব্যবহার করেন তবে এই পদক্ষেপগুলি অনুসরণ করুন:

  • CMSampleBuffer এ থাকা ইমেজ ডেটার ওরিয়েন্টেশন নির্দিষ্ট করুন।

    ইমেজ ওরিয়েন্টেশন পেতে:

    সুইফট

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

    উদ্দেশ্য-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 অবজেক্ট তৈরি করুন:

    সুইফট

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    উদ্দেশ্য-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

3. বারকোডস্ক্যানারের একটি উদাহরণ পান

BarcodeScanner একটি উদাহরণ পান:

সুইফট

let barcodeScanner = BarcodeScanner.barcodeScanner()
// Or, to change the default settings:
// let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)

উদ্দেশ্য-C

MLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner];
// Or, to change the default settings:
// MLKBarcodeScanner *barcodeScanner =
//     [MLKBarcodeScanner barcodeScannerWithOptions:options];

4. ইমেজ প্রক্রিয়া

তারপর, ছবিটি process() পদ্ধতিতে পাস করুন:

সুইফট

barcodeScanner.process(visionImage) { features, error in
  guard error == nil, let features = features, !features.isEmpty else {
    // Error handling
    return
  }
  // Recognized barcodes
}

উদ্দেশ্য-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 বস্তু একটি বারকোড উপস্থাপন করে যা চিত্রে সনাক্ত করা হয়েছিল। প্রতিটি বারকোডের জন্য, আপনি ইনপুট ছবিতে এর আবদ্ধ স্থানাঙ্ক পেতে পারেন, সেইসাথে বারকোড দ্বারা এনকোড করা কাঁচা ডেটাও পেতে পারেন৷ এছাড়াও, বারকোড স্ক্যানার বারকোড দ্বারা এনকোড করা ডেটার ধরন নির্ধারণ করতে সক্ষম হলে, আপনি পার্স করা ডেটা ধারণকারী একটি বস্তু পেতে পারেন।

যেমন:

সুইফট

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

উদ্দেশ্য-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

    যদি স্ক্যানিং গতি গুরুত্বপূর্ণ হয়, আপনি চিত্র ক্যাপচার রেজোলিউশন আরও কম করতে পারেন। যাইহোক, উপরে বর্ণিত ন্যূনতম বারকোড আকারের প্রয়োজনীয়তাগুলি মনে রাখবেন।

    আপনি যদি স্ট্রিমিং ভিডিও ফ্রেমগুলির একটি ক্রম থেকে বারকোডগুলি সনাক্ত করার চেষ্টা করছেন, তাহলে সনাক্তকারী ফ্রেম থেকে ফ্রেমে বিভিন্ন ফলাফল তৈরি করতে পারে৷ আপনি একটি ভাল ফলাফল ফিরিয়ে দিচ্ছেন এই আত্মবিশ্বাসের জন্য আপনি একই মানের একটি ধারাবাহিক সিরিজ না পাওয়া পর্যন্ত অপেক্ষা করুন।

    চেকসাম ডিজিটটি ITF এবং CODE-39-এর জন্য সমর্থিত নয়।

  • ভিডিও ফ্রেম প্রক্রিয়াকরণের জন্য, ডিটেক্টরের results(in:) সিঙ্ক্রোনাস API ব্যবহার করুন। প্রদত্ত ভিডিও ফ্রেম থেকে সুসংগতভাবে ফলাফল পেতে AVCaptureVideoDataOutputSampleBufferDelegate 's captureOutput(_, didOutput:from:) ফাংশন থেকে এই পদ্ধতিতে কল করুন। AVCaptureVideoDataOutput এর alwaysDiscardsLateVideoFrames ডিসকার্ডসলেটভিডিওফ্রেমগুলিকে ডিটেক্টরে কল থ্রোটল করার জন্য true হিসাবে রাখুন৷ ডিটেক্টর চলাকালীন একটি নতুন ভিডিও ফ্রেম উপলব্ধ হলে, এটি বাদ দেওয়া হবে৷
  • আপনি যদি ইনপুট ইমেজে গ্রাফিক্স ওভারলে করার জন্য ডিটেক্টরের আউটপুট ব্যবহার করেন, তাহলে প্রথমে ML Kit থেকে ফলাফল পান, তারপর একটি একক ধাপে চিত্র এবং ওভারলে রেন্ডার করুন। এটি করার মাধ্যমে, আপনি প্রতিটি প্রক্রিয়াকৃত ইনপুট ফ্রেমের জন্য শুধুমাত্র একবার প্রদর্শন পৃষ্ঠে রেন্ডার করবেন। একটি উদাহরণের জন্য ML কিট কুইকস্টার্ট নমুনায় UpdatePreviewOverlayViewWithLastFrame দেখুন।