Szukaj…


Wprowadzenie

Kody QR (Quick Response) to dwuwymiarowe kody kreskowe, które są szeroko stosowane na etykietach optycznych do odczytu maszynowego. iOS zapewnia sposób odczytu kodów QR za pomocą frameworku AVFoundation od iOS 7. Ta struktura zapewnia zestaw interfejsów API do konfigurowania / otwierania kamery i odczytywania kodów QR z kanału kamery.

UIViewController skanuje w poszukiwaniu QR i wyświetla wejście wideo

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 - będzie nazwany na pomyślne skanowania initCaptureSession - initialize skanowanie QR i wejście kamery dismissCaptureSession - ukryj wejście kamera i skanowanie przystanek

Skanowanie kodu QR za pomocą frameworka AVFoudation

Przed iOS 7, gdy chcesz zeskanować kod QR, być może będziemy musieli polegać na zewnętrznych platformach lub bibliotekach, takich jak zBar lub zXing . Ale Apple wprowadziło AVCaptureMetaDataOutput z iOS 7 do odczytu kodów kreskowych.

Aby odczytać kod QR za pomocą AVFoundation , musimy skonfigurować / utworzyć AVCaptureSession i użyć captureOutput:didOutputMetadataObjects:fromConnection: delegate method.

Krok 1

Zaimportuj środowisko AVFoundation i potwierdź protokół AVCaptureMetadataOutputObjectsDelegate

import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate

Krok 2

Odczytywanie kodów QR jest całkowicie oparte na przechwytywaniu wideo. Aby przechwytywać ciągłe wideo, utwórz AVCaptureSession i skonfiguruj wejście i wyjście urządzenia. Dodaj poniższy kod w widoku viewDidLoad metody kontrolera

// 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
}

Krok 3

Zaimplementuj AVCaptureMetadataOutputObjectsDelegate delegowania AVCaptureMetadataOutputObjectsDelegate , aby odczytać kod 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
        }
    }
} 

tutaj obiekt metadanych może również dać ci ograniczenia kodu QR odczytanego na kanale kamery. Aby uzyskać granice, po prostu przekaż obiekt metadanych do metody transformedMetadataObject videoPreviewLayer , jak poniżej.

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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow