WeScan Camera Auto Focus or Select Camera Swift

84 Views Asked by At

I have made an ingredient scanning app in Swift using the WeScan git repo as I only want to scan one image at a time and found issues trying to use native libraries.

https://github.com/WeTransfer/WeScan/

Everything is complete however I was testing on an older iPhone with only 1 rear camera. After testing on an iPhone 15 I have realised the rear camera is not auto focusing and I can't see in the library where to define either which camera to use (it needs the closest vision one for scanning small text) or how to make it auto focus (eg like in the native camera app you tap to auto focus and it will swap to the appropriate camera).

I have been playing around with the ImageScannerController and CameraScannerViewController to no avail trying to find an autoFocus or selectCamera method.

func scanFromCamera() {
    let scannerViewController = ImageScannerController()
    scannerViewController.imageScannerDelegate = self
    scannerViewController.modalPresentationStyle = .popover
    scannerViewController.navigationBar.backgroundColor = .black
    scannerViewController.navigationBar.tintColor = .white
    scannerViewController.toolbar.backgroundColor = .black
    present(scannerViewController, animated: true)
    
}

 private func configureOCR() {
    ocrRequest = VNRecognizeTextRequest { (request, error) in
        guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
        
        var ocrText = ""
        for observation in observations {
            guard let topCandidate = observation.topCandidates(1).first else { return }
            
            ocrText += topCandidate.string + "\n"
        }
        
        DispatchQueue.main.async {
            self.scannedIngedients = ocrText;
            self.performSegue(withIdentifier: "ScanResults", sender: self)
        }
    }
    
    ocrRequest.recognitionLevel = .accurate
    ocrRequest.recognitionLanguages = ["en-US", "en-GB", "en-AU"]
    ocrRequest.usesLanguageCorrection = true
}

private func processImage(_ image: UIImage) {
    guard let cgImage = image.cgImage else { return }
    
    let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
    do {
        try requestHandler.perform([self.ocrRequest])
    } catch {
        print(error)
    }
}

@objc func openCamera(sender: Any) {
    scanFromCamera()
}

Thanks very much.

1

There are 1 best solutions below

0
Adam First On

I have fixed it, putting this here for others who have the same issue or hoping contributors could possibly add this as a function of the app to chose which lens to use.

  1. I downloaded a local copy of the git

  2. In Xcode I removed the dependency on the package from git (Click on the main blue project icon, package dependencies, WeScan, and clicked - )

  3. Added the package dependancy based on the local copy (so I could alter the files of the package) - XCode, File, Add Package Depdancy, click Add Local button, browse for the local copy and add

  4. The following 4 files were where I found the code is selecting AVCaptureDevice (in Scan and Session folders): CameraScannerViewController, CaptureSessionManager, ScannerViewController, CaptureSession

  5. Search for AVCaptureDevice and replace this: guard let device = AVCaptureDevice.default(for: AVMediaType.video) with the following to CameraScannerViewController and ScannerViewController:

    let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTripleCamera, .builtInDualWideCamera, .builtInDualCamera, .builtInWideAngleCamera], mediaType: .video, position: .back) let selectedDevice = discoverySession.devices.first guard let device = selectedDevice else { return }

  6. Add this to CaptureSession:

     let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTripleCamera, .builtInDualWideCamera, .builtInDualCamera, .builtInWideAngleCamera], mediaType: .video, position: .back)
    

    let selectedDevice = discoverySession.devices.first self.device = selectedDevice

  7. And add this to CaptureSessionManager:

    let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTripleCamera, .builtInDualWideCamera, .builtInDualCamera, .builtInWideAngleCamera], mediaType: .video, position: .back)

    let selectedDevice = discoverySession.devices.first guard let device = selectedDevice else { let error = ImageScannerControllerError.inputDevice delegate?.captureSessionManager(self, didFailWithError: error) return nil }

Some links I found helpful:

https://teng.pub/technical/2022/6/9/let-ios-decide-the-best-lens-to-use https://developer.apple.com/documentation/avfoundation/capture_setup/choosing_a_capture_device