Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVCaptureMetadataOutput().rectOfInterest not Working

I am building a UIView that has an overlaid box and the end-goal is to have the QR Code reader only fire when the QR falls within the box. I know that I need to set the .rectOfInterest() to be the same as the yellow box, but in the current implementation (code below), the reader doesn't work.

public override init(frame: CGRect) {
    super.init(frame: frame)

    if let captureDevice = AVCaptureDevice.default(for: .video) {
        do {
            let input = try AVCaptureDeviceInput(device: captureDevice)
            session.addInput(input)
        } catch {
            print("Error")
        }

        let scannerRect = CGRect(x: self.center.x - (self.frame.width * 0.667 / 2), y: self.frame.width * 0.667 / 4, width: self.frame.width * 0.667, height: self.frame.width * 0.667)

        let output = AVCaptureMetadataOutput()
        output.rectOfInterest = scannerRect
        session.addOutput(output)

        output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        output.metadataObjectTypes = [.qr]

        video = AVCaptureVideoPreviewLayer(session: session)
        video.frame = self.layer.bounds

        scannerBounds.frame = scannerRect
        scannerBounds.borderColor = UIColor.yellow.cgColor
        scannerBounds.borderWidth = 5

        self.layer.addSublayer(video)
        self.layer.insertSublayer(scannerBounds, above: video)
    }
}

Please help me align the box and the qr code reader.

enter image description here

like image 779
Caleb Rudnicki Avatar asked Apr 20 '19 19:04

Caleb Rudnicki


1 Answers

First off, are you committing the session config and starting the capture session?

session.commitConfiguration()
session.startRunning()

Next, you need to convert the rect represented in the UIView's coordinates into the coordinate system of the AVCaptureVideoPreviewLayer:

output.rectOfInterest = video.metadataOutputRectConverted(fromLayerRect: scannerRect)

Lastly, you might need to adjust the sequence of things. I was running into an issue where the rect of interest was not working correctly. It turns out that setting rectOfInterest before the view has been fully laid out might cause it not to work as expected.

On iOS 11 and upwards I'm setting rectOfInterest inside the view's safeAreaInsetsDidChange and then starting the camera.

On iOS 10 and lower, I'm doing this in the view controller's viewWillAppear.

like image 143
fphilipe Avatar answered Sep 19 '22 21:09

fphilipe