AVFoundation PDF417扫描仪并非始终可以工作

时间:2018-07-20 03:42:27

标签: swift xcode avfoundation pdf417

我正在使用Swift 4和Xcode 9创建一个应用程序,该应用程序使用AVFoundation扫描PDF417条形码。扫描仪可以使用某些代码,但无法识别例如在CA Lottery刮刮票的正面上找到的PDF417条码。

要使它正常工作,我需要缺少什么吗?下面是我的代码:

let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera], mediaType: AVMediaType.video, position: .back)

    guard let captureDevice = deviceDiscoverySession.devices.first else {
        print("Failed to get the camera device")
        return
    }

    do {
        captureSession = AVCaptureSession()

        let input = try AVCaptureDeviceInput(device: captureDevice)
        captureSession!.addInput(input)

        let captureMetadataOutput = AVCaptureMetadataOutput()

        captureSession!.addOutput(captureMetadataOutput)
        captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.pdf417]

        videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
        videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        videoPreviewLayer?.frame = view.layer.bounds
        view.layer.addSublayer(videoPreviewLayer!)
        captureSession?.startRunning()
     } catch {
        print(error)
        return
    }

 func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {

    //Get the metadata object
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    if scanType.contains(metadataObj.type) {
        let barCodeObj = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)

        if(metadataObj.stringValue != nil) {
            callDelegate(metadataObj.stringValue)
            captureSession?.stopRunning()
            AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
            navigationController?.popViewController(animated: true)
        }
    }
}

谢谢!

1 个答案:

答案 0 :(得分:0)

在您的viewDidLoad或您希望其包含的某些方法中,使用以下代码替换扫描仪的初始化代码

// Global vars used in init below
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!


func setupCaptureInputDevice() {
    let cameraMediaType = AVMediaType.video

    captureSession = AVCaptureSession()

    // get the video capture device, which should be of type video
    guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else {

        // if there is an error then something is wrong, so dismiss
        dismiss(animated: true, completion: nil)
        return

    }

    let videoInput: AVCaptureDeviceInput

    // create a capture input for the above device input that was created
    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        return
    }

    // this is important to check for if we are able to add the input
    // because adding before this could cause a crash or it could not happen
    if (captureSession.canAddInput(videoInput)) {
        captureSession.addInput(videoInput)
    } else {
        // dismiss or display error
        return
    }

    // get ready to capture output somewhere
    let metadataOutput = AVCaptureMetadataOutput()

    // again check to make sure that we can do this operation before doing it
    if (captureSession.canAddOutput(metadataOutput)) {
        captureSession.addOutput(metadataOutput)

        // setting the metadataOutput's delegate to be self and then requesting it run on the main thread
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        // specify your code type
        metadataOutput.metadataObjectTypes = [.pdf417]
    } else {
        // dismiss or display error
        return
    }

    // the preview layer now becomes the capture session
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

    // just add it to the screen
    previewLayer.frame = view.layer.bounds
    previewLayer.videoGravity = .resizeAspectFill
    view.layer.addSublayer(previewLayer)

    // and begin input
    captureSession.startRunning()
}