Recherche…


Introduction

Les codes QR (Quick Response) sont des codes à barres bidimensionnels largement utilisés sur les étiquettes optiques lisibles par une machine. iOS fournit un moyen de lire les codes QR à l'aide de l' AVFoundation partir d'iOS 7 et suivants. Ce framework fournit un ensemble d'API pour configurer / ouvrir la caméra et lire les codes QR à partir du flux de la caméra.

UIViewController recherchant QR et affichant une entrée vidéo

import AVFoundation
class QRScannerViewController: UIViewController,
     AVCaptureMetadataOutputObjectsDelegate {
   
    func viewDidLoad() {
        self.initCaptureSession()
    }
    
    private func initCaptureSession() {
        let captureDevice = AVCaptureDevice
            .defaultDevice(withMediaType: AVMediaTypeVideo)
        do {
            let input = try AVCaptureDeviceInput(device: captureDevice)
            let captureMetadataOutput = AVCaptureMetadataOutput()
            self.captureSession?.addOutput(captureMetadataOutput)
            captureMetadataOutput.setMetadataObjectsDelegate(self,
                 queue: DispatchQueue.main)
            captureMetadataOutput
                .metadataObjectTypes = [AVMetadataObjectTypeQRCode]
            
            self.videoPreviewLayer = 
                AVCaptureVideoPreviewLayer(session: self.captureSession)
            self.videoPreviewLayer?
                .videoGravity = AVLayerVideoGravityResizeAspectFill
            self.videoPreviewLayer?.frame =    
                self.view.layer.bounds

            self._viewController?.view.layer
                .addSublayer(videoPreviewLayer!)
            self.captureSession?.startRunning()
        } catch {
            //TODO: handle input open error
        }
    }
    private func dismissCaptureSession() {
        if let running = self.captureSession?.isRunning, running {
            self.captureSession?.stopRunning()
        }
        self.captureSession = nil
        self.videoPreviewLayer?.removeFromSuperLayer()
        self.videoPreviewLayer = nil
    }
    
    func captureOutput(_ captureOutput: AVCaptureOutput, 
        didOutputMetadataObjects metadataObjects: [Any]!, 
        from connection: AVCaptureConnection) {
        guard metadataObjects != nil && metadataObjects.count != 0 else {
            //Nothing captured
            return
        }

        if let metadataObj = 
            metadataObjects[0] as? AVMetadataMachineReadableCodeObject {
            guard metadataObj.type == AVMetadataObjectTypeQRCode else {
                return
            }

            let barCodeObject = videoPreviewLayer?
                .transformedMetadataObject(for: 
                    metadataObj as AVMetadataMachineReadableCodeObject)
                 as! AVMetadataMachineReadableCodeObject
        
            if let qrValue = metadataObj.stringValue {
                self.handleQRRead(value: qrValue)
            }
        }
    }

    private handleQRRead(value: String) {
        //TODO: Handle the read qr
    }
    private captureSession: AVCaptureSession?
    private videoPreviewLayer: AVCaptureVideo
}

handleQRRead - sera appelée sur une analyse réussie initCaptureSession - initialiser le balayage pour QR et entrée de la caméra dismissCaptureSession - cacher l'entrée de la caméra et arrêter le balayage

Scanner le code QR avec le framework AVFoudation

Avant iOS 7, lorsque vous souhaitiez numériser un code QR, nous devions peut-être utiliser des structures tierces ou des bibliothèques telles que zBar ou zXing . Mais Apple a introduit AVCaptureMetaDataOutput d'iOS 7 pour la lecture des codes à barres.

Pour lire le code QR en utilisant AVFoundation nous devons configurer / créer AVCaptureSession et utiliser captureOutput:didOutputMetadataObjects:fromConnection: méthode delegate.

Étape 1

Importer le framework AVFoundation et confirmer le protocole AVCaptureMetadataOutputObjectsDelegate

import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate

Étape 2

La lecture du code QR est totalement basée sur la capture vidéo. Ainsi, pour capturer des vidéos en continu, créez une AVCaptureSession et configurez les entrées et les sorties des périphériques. Ajoutez le code ci-dessous dans la méthode viewDidLoad contrôleur de vue

// Create an instance of the AVCaptureDevice and provide the video as the media type parameter.
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
 
do {
    // Create an instance of the AVCaptureDeviceInput class using the device object and intialise capture session
    let input = try AVCaptureDeviceInput(device: captureDevice)
    captureSession = AVCaptureSession()
    captureSession?.addInput(input)
    
    // Create a instance of AVCaptureMetadataOutput object and set it as the output device the capture session.
    let captureMetadataOutput = AVCaptureMetadataOutput()
    captureSession?.addOutput(captureMetadataOutput)
    // Set delegate with a default dispatch queue
    captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    //set meta data object type as QR code, here we can add more then one type as well 
    captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]


    // Initialize the video preview layer and add it as a sublayer to the viewcontroller view's layer.
    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    videoPreviewLayer?.frame = view.layer.bounds
    view.layer.addSublayer(videoPreviewLayer!)

    // Start capture session.
    captureSession?.startRunning()
} catch {
    // If any error occurs, let the user know. For the example purpose just print out the error
    print(error)
    return
}

Étape 3

Implémenter la méthode déléguée AVCaptureMetadataOutputObjectsDelegate pour lire le code QR

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
    
    // Check if the metadataObjects array contains at least one object. If not no QR code is in our video capture
    if metadataObjects == nil || metadataObjects.count == 0 {
        // NO QR code is being detected.
        return
    }
    
    // Get the metadata object and cast it to `AVMetadataMachineReadableCodeObject`
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    
    if metadataObj.type == AVMetadataObjectTypeQRCode {
        // If the found metadata is equal to the QR code metadata then get the string value from meta data
        let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
        
        if metadataObj.stringValue != nil {
           // metadataObj.stringValue is our QR code
        }
    }
} 

Ici, les objets de métadonnées peuvent également vous fournir les limites du code QR lu sur le fil de la caméra. Pour obtenir les limites, transmettez simplement l'objet de métadonnées à la méthode transformedMetadataObject videoPreviewLayer comme ci-dessous.

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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow