In this app I get access to QRCode.
Reading works perfectly from the camera.
Now I am struggling to get the image that was processed by the built in QRCode reader.
I have found many hints on SO, but cannot make it work.
Here is the code I have now.
It is a bit long, I have to slit in 2 parts
I looked at:
// https://stackoverflow.com/questions/56088575/how-to-get-image-of-qr-code-after-scanning-in-swift-ios
// https://stackoverflow.com/questions/37869963/how-to-use-avcapturephotooutput
I get the following print on console
Clearly photo is not loaded properly
Do I get here ? false
previewPixelType 875704422
photo <AVCapturePhoto: 0x281973a20 pts:nan 1/1 settings:uid:3 photo:{0x0} time:nan-nan> nil
Error while generating image from photo capture data.
Reading works perfectly from the camera.
Now I am struggling to get the image that was processed by the built in QRCode reader.
I have found many hints on SO, but cannot make it work.
Here is the code I have now.
It is a bit long, I have to slit in 2 parts
I looked at:
// https://stackoverflow.com/questions/56088575/how-to-get-image-of-qr-code-after-scanning-in-swift-ios
// https://stackoverflow.com/questions/37869963/how-to-use-avcapturephotooutput
Code Block import UIKit import AVFoundation class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { fileprivate var captureSession: AVCaptureSession! // use for QRCode reading fileprivate var previewLayer: AVCaptureVideoPreviewLayer! // To get the image of the QRCode private var photoOutputQR: AVCapturePhotoOutput! private var isCapturing = false override func viewDidLoad() { super.viewDidLoad() var accessGranted = false // switch AVCaptureDevice.authorizationStatus(for: .video) { // HERE TEST FOR ACCESS RIGHT. WORKS OK ; // But is .video enough ? } if !accessGranted { return } captureSession = AVCaptureSession() photoOutputQR = AVCapturePhotoOutput() // IS IT THE RIGHT PLACE AND THE RIGHT THING TO DO ? captureSession.addOutput(photoOutputQR) // Goal is to capture an image of QRCode once acquisition is done guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return } let videoInput: AVCaptureDeviceInput do { videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice) } catch { return } if (captureSession.canAddInput(videoInput)) { captureSession.addInput(videoInput) } else { failed() return } let metadataOutput = AVCaptureMetadataOutput() if (captureSession.canAddOutput(metadataOutput)) { captureSession.addOutput(metadataOutput) // SO I have 2 output in captureSession. IS IT RIGHT ? metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) metadataOutput.metadataObjectTypes = [.qr] // For QRCode video acquisition } else { failed() return } previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = view.layer.bounds previewLayer.frame.origin.y += 40 previewLayer.frame.size.height -= 40 previewLayer.videoGravity = .resizeAspectFill view.layer.addSublayer(previewLayer) captureSession.startRunning() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if (captureSession?.isRunning == false) { captureSession.startRunning() } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) if (captureSession?.isRunning == true) { captureSession.stopRunning() } } // MARK: - scan Results func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { captureSession.stopRunning() if let metadataObject = metadataObjects.first { guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return } guard let stringValue = readableObject.stringValue else { return } AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) found(code: stringValue) } // ### Get image - IS IT THE RIGHT PLACE TO DO IT ? // https://stackoverflow.com/questions/37869963/how-to-use-avcapturephotooutput print("Do I get here ?", isCapturing) let photoSettings = AVCapturePhotoSettings() let previewPixelType = photoSettings.availablePreviewPhotoPixelFormatTypes.first! print("previewPixelType", previewPixelType) let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType, kCVPixelBufferWidthKey as String: 160, kCVPixelBufferHeightKey as String: 160] photoSettings.previewPhotoFormat = previewFormat if !isCapturing { isCapturing = true photoOutputQR.capturePhoto(with: photoSettings, delegate: self) } dismiss(animated: true) } } extension ScannerViewController: AVCapturePhotoCaptureDelegate { func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { isCapturing = false print("photo", photo, photo.fileDataRepresentation()) guard let imageData = photo.fileDataRepresentation() else { print("Error while generating image from photo capture data."); return } } }
I get the following print on console
Clearly photo is not loaded properly
Do I get here ? false
previewPixelType 875704422
photo <AVCapturePhoto: 0x281973a20 pts:nan 1/1 settings:uid:3 photo:{0x0} time:nan-nan> nil
Error while generating image from photo capture data.