2

I've been using the native barcode scanner functionality provided by apple since iOS7 and it is great, but I needed to scan some static images I had so I could automatically catalogue some barcodes.

I couldn't find a way to do this natively, so I used an open source package called zBar, and for the most part, it works fine.

However, it returns false values often and sometimes flat out fails to find the barcode. I also built the c++ library from scratch but I got the same results in my OS X build. It also seems to be an abandoned project.

Apple's native solution finds the barcode on this static image even if I scan the image from my computer monitor! Same thing goes for the images that return false/incorrect values.

So is there anyway to use apple's libraries to scan a UIImage?

StainlessSteelRat
  • 364
  • 1
  • 2
  • 16
  • Have you found any solution for that or it is not possible for now? – slava May 18 '15 at 08:15
  • No, unfortunately not. – StainlessSteelRat May 25 '15 at 20:46
  • CIDetector for QRCodes on UIImage. Check documentation. http://stackoverflow.com/questions/28317071/scan-qrcode-and-barcode-from-camera-and-image-which-picked-from-image-library-in –  Sep 22 '15 at 21:27
  • zxing objc port seems to be quite updated now. And from my few testing it recognizing better than CoreImage do. Even if CI do encoding. See https://github.com/TheLevelUp/ZXingObjC – alexey.metelkin Dec 11 '15 at 11:50

2 Answers2

0

Try this

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;
  }
}
StefanS
  • 1,089
  • 1
  • 11
  • 38
Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179
  • Unfortunately I so far have not gotten this to work. Sometimes the UIImage doesn't have a CIImage, and you have to manually recreate it. Even then the code is never returning a barcode for me. Still investigating – StainlessSteelRat Mar 19 '16 at 23:43
0

An option available now is MLKit from Firebase.

Add Firebase to your project after setting up your project in their console https://firebase.google.com

I use cocoapods to manage dependencies, if you do then add this to your Podfile and pod update:

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

Here's a demo view controller implementation in which you pick a barcode image from your photo library to be scanned by ML kit, and the results are printed in a label.

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

Here's a link to their documentation: https://firebase.google.com/docs/ml-kit/ios/read-barcodes

digitalHound
  • 4,384
  • 27
  • 27