Nam
Nam

Reputation: 1876

Improve Barcode scanner in Swift

I've implemented barcode scanning following the "standards" around the tutorials. But I think the performance is kind of terrible. I can point my camera against a barcode with perfekt focus and no glare and still the code doesnt detect the barcode.

And I'm kind of jealous of the app ScanLife - its amazingly fast and detect codes without even being in focus.

Any ideas how to improve scanning?

Here's a snippet of my code (the detection part):

var captureSession: AVCaptureSession!
    var previewLayer: AVCaptureVideoPreviewLayer!
    let videoCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    captureSession = AVCaptureSession()

    let videoInput: AVCaptureDeviceInput

    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)

        if captureSession.canAddInput(videoInput) {
            captureSession.addInput(videoInput)

            let metadataOutput = AVCaptureMetadataOutput()

            if captureSession.canAddOutput(metadataOutput) {
                captureSession.addOutput(metadataOutput)

                metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
                metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes // Use all metadata object types by default.
                metadataOutput.rectOfInterest = CGRect.zero

            } else {
                failed()
                return
            }

            if (videoCaptureDevice?.isFocusModeSupported(.continuousAutoFocus))! {
                do {
                    if(try videoCaptureDevice?.lockForConfiguration()) != nil {
                        videoCaptureDevice?.exposureMode = .continuousAutoExposure
                        videoCaptureDevice?.focusMode = .continuousAutoFocus
                        videoCaptureDevice?.unlockForConfiguration()
                    }
                } catch {

                }
            }

            videoCaptureDevice?.addObserver(self, forKeyPath: "adjustingFocus", options: NSKeyValueObservingOptions.new, context: nil)
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ScannerViewController.focus(_:)))
            mainView.addGestureRecognizer(tapGesture)

            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
            previewLayer.frame = view.layer.bounds;
            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            mainView.layer.addSublayer(previewLayer);

            /*
            // Initialize code Frame to highlight the code
            codeFrameView.layer.borderColor = UIColor.green.cgColor
            codeFrameView.layer.borderWidth = 2
            view.addSubview(codeFrameView)
            view.bringSubview(toFront: codeFrameView)
            */

            captureSession.startRunning()

        } else {
            failed()
        }
    } catch {
        failed()
    }

Upvotes: 2

Views: 2200

Answers (1)

Nam
Nam

Reputation: 1876

For whats its worth, it seem to improve the performance to define a rect to search in. Also as the documentation says:

Specifying a rectOfInterest may improve detection performance for certain types of metadata.

Code could be

metadataOutput.rectOfInterest = focusView.frame

Where focusView is a view displayed on top of the preview layer, to signal

Upvotes: 3

Related Questions