Как получить изображение qr-кода после сканирования в swift ios? - PullRequest
1 голос
/ 11 мая 2019

Я занимаюсь разработкой приложения для чтения QR-кодов в Xcode с помощью swift. Я отсканировал QR-код со следующим кодом:

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
    }

}

после сканирования qr-кода, я хочу получить изображение qr-кода и установить изображение testImageView для полученного изображения. Как это возможно? Я делаю это, потому что я хочу сохранить это изображение в базе данных для будущего использования. Здесь Мой единственный вопрос - как получить изображение qr-кода из videoPreviewLayer и установить для него изображение testImageView.

1 Ответ

0 голосов
/ 11 мая 2019

Вы можете добавить AVCapturePhotoOutput и capturePhoto при необходимости.

  1. Добавьте два свойства в ScannerViewController:

    private let photoOutput = AVCapturePhotoOutput()
    private var isCapturing = false
    
  2. Добавить новый вывод в captureSession при viewDidLoad:

    captureSession.addOutput(photoOutput)
    
  3. Вызвать capturePhoto в методе metadataOutput и запомнить состояние захвата. Поскольку метод metadataOutput может вызываться очень часто:

    let photoSettings = AVCapturePhotoSettings()
    if !isCapturing {
        isCapturing = true
        photoOutput.capturePhoto(with: photoSettings, delegate: self)
    }
    
  4. Реализация протокола 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. Также неплохо сделать некоторые дополнительные настройки фото и обработать ошибки, если это необходимо.

...