使用视觉框架扫描轮胎二维码?

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

iOS 内置支持使用 AVFoundation 和视觉框架 扫描二维码,但代码并不容易:您需要创建捕获会话、创建预览层、处理委托回调等。为了让您更轻松,我创建了一个 UIViewController 子类,它为您完成所有艰苦的工作——您只需要修改 found(code:) 方法来做一些更有趣的事情。

注意:- 使用相机时的旋转可能非常难看,这就是为什么大多数应用程序会固定方向,如下所示。

import Foundation
import UIKit
import AVFoundation
import Vision

class qrVC: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    
    var captureSession: AVCaptureSession!
    var previewLayer: AVCaptureVideoPreviewLayer!
    let filter = CIFilter(name: "CIPhotoEffectMono")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        captureSession = AVCaptureSession()
        captureSession.startRunning()
        
        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
        let videoInput: AVCaptureDeviceInput
        
        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            return
        }
        
        if (captureSession.canAddInput(videoInput)) {
            captureSession.addInput(videoInput)
        } else {
            return
        }
        
        let videoOutput = AVCaptureVideoDataOutput()
        videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
        captureSession.addOutput(videoOutput)
        videoOutput.connection(with: .video)?.videoOrientation = .portrait
        
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        view.layer.addSublayer(previewLayer)
        
        
    }
    
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
        let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: .up, options: [:])
        guard let filteredPixelBuffer = applyFilter(to: pixelBuffer) else { return }
        
        let previewImage = CIImage(cvPixelBuffer: filteredPixelBuffer)
        let context = CIContext()
        guard let previewCGImage = context.createCGImage(previewImage, from: previewImage.extent) else { return }
        DispatchQueue.main.async {
            self.previewLayer.contents = previewCGImage
        }
        
        
        do {
            try imageRequestHandler.perform([detectQRCodeRequest])
        } catch {
            print(error)
        }
    }
    //-----------------------------------------------------
    // ----- detectQRCodeRequest -----
    lazy var detectQRCodeRequest: VNDetectBarcodesRequest = {
        let detectBarcodeRequest = VNDetectBarcodesRequest(completionHandler: { request, error in
            if let results = request.results {
                if let result = results.first as? VNBarcodeObservation {
                    if let payload = result.payloadStringValue {
                        DispatchQueue.main.async {
                            // Handle the decoded payload string value here
                            print(payload)
                            
                            
                            let alert = UIAlertController(title: "Alert", message: payload, preferredStyle: UIAlertController.Style.alert)
                            alert.addAction(UIAlertAction(title: "Click", style: UIAlertAction.Style.default, handler: nil))
                            self.present(alert, animated: true, completion: nil)
                        }
                    }
                }
            }
        })
        detectBarcodeRequest.symbologies = [.qr, .ean8, .ean13, .pdf417, .aztec, .code39, .code93, .code128,  .itf14, .dataMatrix]
        return detectBarcodeRequest
    }()
    //-----------------------------------------------------
    func applyFilter(to pixelBuffer: CVPixelBuffer) -> CVPixelBuffer? {
        // Convert pixel buffer to CIImage
        let image = CIImage(cvPixelBuffer: pixelBuffer)
        
        // Apply filter to CIImage
        filter?.setValue(image, forKey: kCIInputImageKey)
        guard let outputImage = filter?.outputImage else { return nil }
        
        // Render filtered CIImage to CVPixelBuffer
        var outputPixelBuffer: CVPixelBuffer?
        CVPixelBufferCreate(nil, Int(outputImage.extent.width), Int(outputImage.extent.height), kCVPixelFormatType_32BGRA, nil, &outputPixelBuffer)
        let context = CIContext()
        context.render(outputImage, to: outputPixelBuffer!)
        
        return outputPixelBuffer
    }
}


二维码图片

https://i.stack.imgur.com/PIzdV.png)(https://i.stack.imgur.com/Cb40G.png)(https://i.stack.imgur.com/LJuvw.png

ios swift qr-code vision
© www.soinside.com 2019 - 2024. All rights reserved.