条码扫描器无法读取所有内容

问题描述 投票:1回答:1

我正在编写一个读取条形码的应用程序,但遇到了一个问题:仅读取高质量的条形码。如果卡纸很小或有一点卡住,将不再读取。你能告诉我们如何处理这个问题吗?

下面的代码

    import UIKit
    import AVFoundation
    import AudioToolbox
    import CoreData

    class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    @IBOutlet weak var infoLbl: UILabel!
    @IBOutlet weak var barcodeButton1: UIButton!

    @IBOutlet weak var blueButton: UIButton!


    let systemSoundId : SystemSoundID = 1016

    //captureSession manages capture activity and coordinates between input device and captures outputs
    var captureSession:AVCaptureSession?
    var videoPreviewLayer:AVCaptureVideoPreviewLayer?

    //Empty Rectangle with green border to outline detected QR or BarCode
    let codeFrame:UIView = {
        let codeFrame = UIView()
        codeFrame.layer.borderColor = UIColor.red.cgColor
        codeFrame.layer.borderWidth = 1.5
        codeFrame.frame = CGRect.zero
        codeFrame.translatesAutoresizingMaskIntoConstraints = false
        return codeFrame
    }()

    override func viewDidDisappear(_ animated: Bool) {
        captureSession?.stopRunning()
    }

    override func viewDidAppear(_ animated: Bool) {
        captureSession?.startRunning()
    }

    func toggleTorch(on: Bool) {
        guard
            let device = AVCaptureDevice.default(for: AVMediaType.video),
            device.hasTorch
            else { return }

        do {
            try device.lockForConfiguration()
            device.torchMode = on ? .on : .off
            device.unlockForConfiguration()
        } catch {
            print("Torch could not be used")
        }
    }
    var lightOnTouch = false
    @IBAction func lightingOn(_ sender: Any) {
        if !lightOnTouch {
            toggleTorch(on: true)
            lightOnTouch = true
        }
        else {
            toggleTorch(on: false)
            lightOnTouch = false
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view?.backgroundColor = UIColor(white: 1, alpha: 0.5)
        view?.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        //AVCaptureDevice allows us to reference a physical capture device (video in our case)
        let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
        if let captureDevice = captureDevice {
            do {
                /*
                 // Начало автофокуса
                 let w = UIScreen.main.bounds.width
                 let h = UIScreen.main.bounds.height
                 try! captureDevice.lockForConfiguration()
                 if captureDevice.isFocusPointOfInterestSupported {
                 //Add Focus on Point
                 captureDevice.focusPointOfInterest = CGPoint(x: w / 2, y: h / 2)
                 captureDevice.focusMode = AVCaptureDevice.FocusMode.autoFocus
                 }

                 if captureDevice.isExposurePointOfInterestSupported{
                 //Add Exposure on Point
                 captureDevice.exposurePointOfInterest = CGPoint(x: w / 2, y: h / 2)
                 captureDevice.exposureMode = AVCaptureDevice.ExposureMode.autoExpose
                 }
                 captureDevice.unlockForConfiguration()
                 // Конец автофокуса
                 */

                captureSession = AVCaptureSession()
                // CaptureSession needs an input to capture Data from
                let input = try AVCaptureDeviceInput(device: captureDevice)
                captureSession?.addInput(input)

                // CaptureSession needs and output to transfer Data to
                let captureMetadataOutput = AVCaptureMetadataOutput()
                captureSession?.addOutput(captureMetadataOutput)

                //We tell our Output the expected Meta-data type
                captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
                captureMetadataOutput.metadataObjectTypes = [.code128, .ean13, .ean8, .code39, .upce, .code93, .code39Mod43, .itf14] //AVMetadataObject.ObjectType
                captureSession?.startRunning()

                //The videoPreviewLayer displays video in conjunction with the captureSession
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.videoGravity = .resizeAspectFill
                videoPreviewLayer?.frame = view.layer.bounds

                view.layer.addSublayer(videoPreviewLayer!)
                view.bringSubviewToFront(infoLbl)
                view.bringSubviewToFront(barcodeButton1)
            }


            catch {

                print("Error")

            }
        }

    }

    // the metadataOutput function informs our delegate (the ScannerViewController) that the captureOutput emitted a new metaData Object
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if metadataObjects.count == 0 {
            print("no objects returned")
            return
        }

        let metaDataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
        guard let StringCodeValue = metaDataObject.stringValue else {
            return
        }
        view.addSubview(codeFrame)


        //transformedMetaDataObject returns layer coordinates/height/width from visual properties
        guard let metaDataCoordinates = videoPreviewLayer?.transformedMetadataObject(for: metaDataObject) else {
            return
        }
        //Those coordinates are assigned to our codeFrame
        codeFrame.frame = metaDataCoordinates.bounds
        AudioServicesPlayAlertSound(systemSoundId)
        infoLbl.text = StringCodeValue
        if URL(string: StringCodeValue) != nil {
            performSegue(withIdentifier: "seg1", sender: self)
            captureSession?.stopRunning()
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let nextVC = segue.destination as? DetailsViewController {
            nextVC.scannedCode = infoLbl.text
        }
    }
}

读取:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS96QlZabS5qcGcifQ==” alt =“在此处输入图像描述”>未读:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9vdGpsSy5qcGcifQ==” alt =“在此处输入图像描述”>只是说,杂货店中有10%的产品未被读取

请帮助我?

swift barcode barcode-scanner reader
1个回答
0
投票

您仍在使用AVFoundation。实际上,苹果已经发布了比AVFoundation更强大的视觉框架。

enter image description here

如果AVFoundation不理想,您可以尝试Vision API读取条形码。

© www.soinside.com 2019 - 2024. All rights reserved.