简体   繁体   English

在Swift iOS中扫描后如何获取二维码图像?

[英]How to get image of qr-code after scanning in swift ios?

I am developing a qr-code reader app in Xcode with swift. 我正在用Xcode快速开发一个二维码阅读器应用程序。 I scanned qr-code with the following code: 我用以下代码扫描了二维码:

import UIKit
import AVFoundation

class ScannerViewController: UIViewController {

    var captureSession = AVCaptureSession()

    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    var qrCodeFrameView: UIView?

    var scannerMetadataObj : AVMetadataMachineReadableCodeObject?

    @IBOutlet weak var testImageView: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()


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

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

        do {

            let input = try AVCaptureDeviceInput(device: captureDevice)

            captureSession.addInput(input)

            let captureMetadataOutput = AVCaptureMetadataOutput()
            captureSession.addOutput(captureMetadataOutput)

            captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            captureMetadataOutput.metadataObjectTypes = supportedCodeTypes

        } catch {
            return
        }

        videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        videoPreviewLayer?.frame = view.layer.bounds
        view.layer.addSublayer(videoPreviewLayer!)

        qrCodeFrameView = UIView()

        if let qrCodeFrameView = qrCodeFrameView {
            qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
            qrCodeFrameView.layer.borderWidth = 2
            view.addSubview(qrCodeFrameView)
            view.bringSubviewToFront(qrCodeFrameView)
        }


    }


    override func viewWillAppear(_ animated: Bool) {
        captureSession.startRunning()

    }

    override func viewWillDisappear(_ animated: Bool) {
        captureSession.stopRunning()
        qrCodeFrameView?.frame = CGRect.zero
    }

}


extension ScannerViewController: AVCaptureMetadataOutputObjectsDelegate {

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        // Check if the metadataObjects array is not nil and it contains at least one object.
        if metadataObjects.count == 0 {
            qrCodeFrameView?.frame = CGRect.zero
            return
        }


        // Get the metadata object.
        let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

        scannerMetadataObj = metadataObj

        let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
        qrCodeFrameView?.frame = barCodeObject!.bounds

        self.testImageView.image = // set image with qr-code
    }

}

after scanning qr-code, I want to get image of qr-code and set image of testImageView to obtained image. 扫描二维码后,我想获取二维码的图像并将testImageView的图像设置为获得的图像。 How it is possible? 怎么可能? I am doing this because I want to save that image in database for future use. 我这样做是因为我想将该图像保存在数据库中以备将来使用。 Here My only question is how to get image of qr-code from videoPreviewLayer and set image of testImageView to that image. 在这里,我唯一的问题是如何从videoPreviewLayer获取qr代码的图像并将testImageView的图像设置为该图像。

You can add AVCapturePhotoOutput and capturePhoto when needed. 您可以在需要时添加AVCapturePhotoOutput和capturePhoto。

  1. Add two properties at ScannerViewController: 在ScannerViewController上添加两个属性:

     private let photoOutput = AVCapturePhotoOutput() private var isCapturing = false 
  2. Add new output to captureSession at viewDidLoad: 在viewDidLoad处将新的输出添加到captureSession:

     captureSession.addOutput(photoOutput) 
  3. Invoke capturePhoto at metadataOutput method and remember capturing state. 在metadataOutput方法上调用capturePhoto并记住捕获状态。 Because metadataOutput method can be invoked very often: 因为metadataOutput方法可以经常调用:

     let photoSettings = AVCapturePhotoSettings() if !isCapturing { isCapturing = true photoOutput.capturePhoto(with: photoSettings, delegate: self) } 
  4. Implement AVCapturePhotoCaptureDelegate protocol: 实现AVCapturePhotoCaptureDelegate协议:

     extension ScannerViewController: AVCapturePhotoCaptureDelegate { func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { isCapturing = false guard let imageData = photo.fileDataRepresentation() else { print("Error while generating image from photo capture data."); return } guard let qrImage = UIImage(data: imageData) else { print("Unable to generate UIImage from image data."); return } testImageView.image = qrImage } } 
  5. Also good idea to make some additional photo settings and error handling if needed. 如果需要,还可以进行一些其他照片设置和错误处理,也是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM