在iOS上使用ML Kit扫描条形码

您可以使用ML kit来识别并且解码条码。

有关此API使用的示例,请参阅GitHub上的ML Kit快速入门示例。

在开始之前

  1. 如果您还没有将Firebase添加到您的程序当中,那您可以从开始指南来开始您的工作。

  2. 将ML kit库放进您的Podfile中:

    1. pod 'Firebase/Core'
    2. pod 'Firebase/MLVision'
    3. pod 'Firebase/MLVisionBarcodeModel'

​ 而后每次您要安装或者升级您的Pods的时候,请确保使用您的Xcode项目的.xcworkspace来打开它。

  1. 在您的程序中,引入Firebase:

    Swift:

    1. import Firebase

    Objective-C:

    1. @import Firebase;

配置条形码识别器

如果您知道您希望读取哪种条形码格式,可以通过将其配置为仅检测这些格式来提高条形码识别器的识别速度。

Swift:

例如,假设只希望识别Aztec和QR码,您可以构建一个VisionBarcodeDetectorOptions 对象,如下所示:

  1. let format = VisionBarcodeFormat.all
  2. // 或者, e.g.: VisionBarcodeFormat.qrCode | VisionBarcodeFormat.aztec
  3. let options = VisionBarcodeDetectorOptions(formats: format)

Objective-C:

例如,假设只希望识别Aztec和QR码,您可以构建一个 FIRVisionBarcodeDetectorOptions 对象,如下所示:

  1. FIRVisionBarcodeDetectorOptions *options =
  2. [[FIRVisionBarcodeDetectorOptions alloc]
  3. initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];

支持以下格式:

Swift:

  • Code128
  • Code39
  • Code93
  • CodaBar
  • EAN13
  • EAN8
  • ITF
  • UPCA
  • UPCE
  • DataMatrix
  • QRCode
  • PDF417
  • Aztec

Objective-C:

  • Code 128 (FIRVisionBarcodeFormatCode128)
  • Code 39 (FIRVisionBarcodeFormatCode39)
  • Code 93 (FIRVisionBarcodeFormatCode93)
  • Codabar (FIRVisionBarcodeFormatCodaBar)
  • EAN-13 (FIRVisionBarcodeFormatEAN13)
  • EAN-8 (FIRVisionBarcodeFormatEAN8)
  • ITF (FIRVisionBarcodeFormatITF)
  • UPC-A (FIRVisionBarcodeFormatUPCA)
  • UPC-E (FIRVisionBarcodeFormatUPCE)
  • Data Matrix (FIRVisionBarcodeFormatDataMatrix)
  • QR Code (FIRVisionBarcodeFormatQRCode)
  • PDF417 (FIRVisionBarcodeFormatPDF417)
  • Aztec (FIRVisionBarcodeFormatAztec)

运行条形码识别器

为了能够识别图像中的条形码,将图像传递为UIImage或者CMSampleBufferRefVisionBarcodeDetectordetect(in:)方法:

  1. 得到一个VisionTextDetector实例:

    Swift:

    1. lazy var vision = Vision.vision()
    2. let barcodeDetector = vision.barcodeDetector(options: options) // 检查错误。
    3. // 或者使用默认设置:
    4. // let barcodeDetector = vision?.barcodeDetector()

    Objective-C:

    1. FIRVision *vision = [FIRVision vision];
    2. FIRVisionBarcodeDetector *detector = [vision barcodeDetector];
    3. // 或者修改默认设置:
    4. // FIRVisionBarcodeDetector *detector =
    5. // [vision barcodeDetectorWithOptions:options];
  2. 使用UIImage 或者 CMSampleBufferRef创建 VisionImage 对象。

    使用UIImage :

    • 如果有必要,旋转图像,使得它的imageOrientation的属性是.up

    • VisionImage使用正确旋转的对象创建一个对象 UIImage。不要指定任何旋转元数据 - 默认值.topLeft,必须使用。

      Swift:

      1. let image = VisionImage(image: uiImage)

      Objective-C:

      1. FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    使用CMSampleBufferRef

    1. 创建一个VisionImageMetadata对象,该对象指定包含在CMSampleBufferRef缓冲区中的图像数据的方向 。

      例如,如果图像数据必须顺时针旋转90度才能保持直立:

      Swift:

      1. let metadata = VisionImageMetadata()
      2. metadata.orientation = .rightTop // Row为0在右边,column为0则是在顶端

      Objective-C:

      1. // Row为0在右边,column为0则是在顶端
      2. FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      3. metadata.orientation = FIRVisionDetectorImageOrientationRightTop;
    2. VisionImage使用CMSampleBufferRef对象和旋转元数据创建一个对象 :

      Swift:

      1. let image = VisionImage(buffer: bufferRef)
      2. image.metadata = metadata

      Objective-C:

      1. FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:buffer];
      2. image.metadata = metadata;
  3. 然后,将图像传递给该detect(in:)方法:

    Swift:

    1. barcodeDetector.detect(in: visionImage) { (barcodes, error) in
    2. guard error == nil, let barcodes = barcodes, !barcodes.isEmpty else {
    3. // 错误,您应该检查控制台。
    4. // ...
    5. return
    6. }
    7. // 识别并且解读条形码
    8. // ...
    9. }

    Objective-C:

    1. [detector detectInImage:image
    2. completion:^(NSArray<FIRVisionBarcode *> *barcodes,
    3. NSError *error) {
    4. if (error != nil) {
    5. return;
    6. } else if (barcodes != nil) {
    7. // 识别条形码
    8. // ...
    9. }
    10. }];

从条形码获取信息

如果条形码识别操作成功,则识别器将返回一个VisionBarcode对象数组 。每个VisionBarcode对象代表图像中检测到的条形码。对于每个条形码,您可以在输入图像中获取其边界坐标以及由条形码编码的原始数据。此外,如果条形码识别器能够确定条形码编码的数据类型,则可以获取包含解析数据的对象。

Swift:

  1. for barcode in barcodes {
  2. let corners = barcode.cornerPoints
  3. let displayValue = barcode.displayValue
  4. let rawValue = barcode.rawValue
  5. let valueType = barcode.valueType
  6. switch valueType {
  7. case .wiFi:
  8. let ssid = barcode.wifi!.ssid
  9. let password = barcode.wifi!.password
  10. let encryptionType = barcode.wifi!.type
  11. case .URL:
  12. let title = barcode.url!.title
  13. let url = barcode.url!.url
  14. default:
  15. // 所有支持的数据类型请查看API列表
  16. }
  17. }

Objective-C:

  1. for (FIRVisionBarcode *barcode in barcodes) {
  2. NSArray *corners = barcode.cornerPoints;
  3. NSString *displayValue = barcode.displayValue;
  4. NSString *rawValue = barcode.rawValue;
  5. FIRVisionBarcodeValueType valueType = barcode.valueType;
  6. switch (valueType) {
  7. case FIRVisionBarcodeValueTypeWiFi:
  8. // ssid = barcode.wifi.ssid;
  9. // password = barcode.wifi.password;
  10. // encryptionType = barcode.wifi.type;
  11. break;
  12. case FIRVisionBarcodeValueTypeURL:
  13. // url = barcode.URL.url;
  14. // title = barcode.URL.title;
  15. break;
  16. // ...
  17. default:
  18. break;
  19. }
  20. }