I've been implementing a test of the new Vision framework which Apple introduced in WWDC2017. I am specifically looking at the barcode detection - I've been able to get after scanning the image from Camera/Gallery that it's a barcode image or not. However, I can't see what the actual barcode value or the payload data when looking at the barcodeDescriptor. There appears to be nothing exposed on the https://developer.apple.com/documentation/coreimage/cibarcodedescriptor page to identify any of the properties.
I am getting these errors:
- Cannot connect to remote service: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named
com.apple.BarcodeSupport.BarcodeNotificationService"- libMobileGestalt MobileGestalt.c:555: no access to InverseDeviceID (see problem/11744455>)
- connection to service named com.apple.BarcodeSupport.BarcodeNotificationService Error
Domain=NSCocoaErrorDomain Code=4097
Is there any way to access the barcode value from the VNBarcodeObservation? Any help would be greatly appreciated. Thank you! Here is the code I am using:
@IBAction func chooseImage(_ sender: Any) {
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
@IBAction func takePicture(_ sender: Any) {
if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)){
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
self .present(imagePicker, animated: true, completion: nil)
}
else{
let alert = UIAlertController(title: "Warning", message: "Camera not available", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
//PickerView Delegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
imagePicker .dismiss(animated: true, completion: nil)
classificationLabel.text = "Analyzing Image…"
guard let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
else { fatalError("no image from image picker") }
guard let ciImage = CIImage(image: pickedImage)
else { fatalError("can't create CIImage from UIImage") }
imageView.image = pickedImage
inputImage = ciImage
// Run the rectangle detector, which upon completion runs the ML classifier.
let handler = VNImageRequestHandler(ciImage: ciImage, options: [.properties : ""])
DispatchQueue.global(qos: .userInteractive).async {
do {
try handler.perform([self.barcodeRequest])
} catch {
print(error)
}
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
picker .dismiss(animated: true, completion: nil)
print("picker cancel.")
}
lazy var barcodeRequest: VNDetectBarcodesRequest = {
return VNDetectBarcodesRequest(completionHandler: self.handleBarcodes)
}()
func handleBarcodes(request: VNRequest, error: Error?) {
guard let observations = request.results as? [VNBarcodeObservation]
else { fatalError("unexpected result type from VNBarcodeRequest") }
guard observations.first != nil else {
DispatchQueue.main.async {
self.classificationLabel.text = "No Barcode detected."
}
return
}
// Loop through the found results
for result in request.results! {
// Cast the result to a barcode-observation
if let barcode = result as? VNBarcodeObservation {
// Print barcode-values
print("Symbology: \(barcode.symbology.rawValue)")
if let desc = barcode.barcodeDescriptor as? CIQRCodeDescriptor {
let content = String(data: desc.errorCorrectedPayload, encoding: .utf8)
// FIXME: This currently returns nil. I did not find any docs on how to encode the data properly so far.
print("Payload: \(String(describing: content))\n")
print("Error-Correction-Level: \(desc.errorCorrectedPayload)\n")
print("Symbol-Version: \(desc.symbolVersion)\n")
}
}
}
}
Yes. iPhones with iOS 11 and above have an in-built QR Code scanner that can be accessed via the native camera app, Control Center, and Google Lens.
You can use Camera or the Code Scanner to scan Quick Response (QR) codes for links to websites, apps, coupons, tickets, and more. The camera automatically detects and highlights a QR code.
The Vision framework performs face and face landmark detection, text detection, barcode recognition, image registration, and general feature tracking. Vision also allows the use of custom Core ML models for tasks like classification or object detection.
Apparently, in the iOS 11 beta 5 Apple introduced new payloadStringValue property of VNBarcodeObservation
. Now you can read info from QR-code with no problems
if let payload = barcodeObservation.payloadStringValue {
print("payload is \(payload)")
}
If Apple is not going to provide a library for this, something like the following will work:
extension CIQRCodeDescriptor {
var bytes: Data? {
return errorCorrectedPayload.withUnsafeBytes { (pointer: UnsafePointer<UInt8>) in
var cursor = pointer
let representation = (cursor.pointee >> 4) & 0x0f
guard representation == 4 /* byte encoding */ else { return nil }
var count = (cursor.pointee << 4) & 0xf0
cursor = cursor.successor()
count |= (cursor.pointee >> 4) & 0x0f
var out = Data(count: Int(count))
guard count > 0 else { return out }
var prev = (cursor.pointee << 4) & 0xf0
for i in 2...errorCorrectedPayload.count {
if (i - 2) == count { break }
let cursor = pointer.advanced(by: Int(i))
let byte = cursor.pointee
let current = prev | ((byte >> 4) & 0x0f)
out[i - 2] = current
prev = (cursor.pointee << 4) & 0xf0
}
return out
}
}
}
And then
String(data: descriptor.bytes!, encoding: .utf8 /* or whatever */)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With