本地从 UIImage 扫描条形码(即不使用 ZBar)

Scanning barcode from UIImage natively (i.e., not using ZBar)

自 iOS7 以来,我一直在使用 apple 提供的本机条码扫描器功能,它很棒,但我需要扫描我拥有的一些静态图像,以便自动对一些条码进行分类。

我找不到在本地执行此操作的方法,所以我使用了一个名为 zBar 的开源包,并且在大多数情况下,它工作正常。

但是,它 return 的错误值经常出现,有时甚至无法找到条形码。我还从头开始构建了 c++ 库,但在我的 OS X 构建中得到了相同的结果。这似乎也是一个废弃的项目。

即使我从计算机显示器扫描图像,Apple 的本机解决方案也能找到此静态图像上的条形码! return false/incorrect 值的图像也是如此。

那么有没有办法使用 apple 的库来扫描 UIImage?

试试这个

CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
if (detector)  {
  NSArray* featuresR = [detector featuresInImage:scannedImg.CIImage];
  NSString* decodeR;
  for (CIQRCodeFeature* featureR in featuresR)  {
    NSLog(@"decode %@ ",featureR.messageString);
    decodeR = featureR.messageString;
  }
}

现在可用的选项是来自 Firebase 的 MLKit。

在他们的控制台中设置您的项目后,将 Firebase 添加到您的项目中 https://firebase.google.com

我使用 cocoapods 来管理依赖项,如果您这样做,请将其添加到您的 Podfile 中 pod update:

pod 'Firebase/Core'
pod 'Firebase/MLVision'
pod 'Firebase/MLVisionBarcodeModel'

这是一个演示视图控制器实现,您可以在其中从照片库中选择条形码图像以供 ML 套件扫描,并将结果打印在标签中。

// (Don't forget to ask for Photos access by including this in your info.plist)

    <key>NSPhotoLibraryUsageDescription</key>
    <string>Enable photo library access to select a photo from your library.</string>



import Firebase

class MyDemoViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    lazy var vision = Vision.vision()
    @IBOutlet var textLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func selectImage(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
            print("Button capture")

            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = .savedPhotosAlbum;
            imagePicker.allowsEditing = false

            self.present(imagePicker, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
            return
        }

        dismiss(animated: true, completion: {
            self.checkForCodeInImage(image: image)
        })
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion:nil)
    }

    internal func checkForCodeInImage(image: UIImage) {
        let detector = vision.barcodeDetector(options: VisionBarcodeDetectorOptions(formats: .all))
        let vImage = VisionImage(image: image)

        detector.detect(in: vImage) { features, error in
            guard error == nil, let barcodes = features, barcodes.isEmpty == false else {
                DispatchQueue.main.async {
                    self.textLabel.text = "No code found in selected image."
                }
                return
            }

            var text = ""

            for barcode in barcodes {

                guard let rawValue = barcode.rawValue else {
                    continue
                }

                let corners = barcode.cornerPoints
                let displayValue = barcode.displayValue

                print("Corners: \(String(describing: corners))")
                print("Found: \(String(describing: displayValue))")

                text.append(rawValue)
                text.append("\n\n")

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

            DispatchQueue.main.async {
                self.textLabel.text = text
            }
        }
    }
}

这是他们文档的 link:https://firebase.google.com/docs/ml-kit/ios/read-barcodes