티스토리 뷰

Develop/iOS

[iOS] Swift QRCode 읽기

Nebori 2018. 8. 26. 19:12

QRCode 읽기

class className: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
    var captureSession:AVCaptureSession?
    var videoPreviewLayer:AVCaptureVideoPreviewLayer?
    
    override func viewDidDisappear(_ animated: Bool) {
        captureSession?.stopRunning()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        captureSession?.startRunning()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //AVCaptureDevice allows us to reference a physical capture device (video in our case)
        let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
        
        if let captureDevice = captureDevice {
            
            do {
                captureSession = AVCaptureSession()
                
                // CaptureSession needs an input to capture Data from
                let input = try AVCaptureDeviceInput(device: captureDevice)
                captureSession?.addInput(input)
                
                // CaptureSession needs and output to transfer Data to
                let captureMetadataOutput = AVCaptureMetadataOutput()
                
                //We tell our Output the expected Meta-data type
                captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
                captureMetadataOutput.metadataObjectTypes = [.code128, .qr, .ean13, .ean8, .code39, .upce, .aztec, .pdf417]
                
                captureSession?.startRunning()
                
                //The videoPreviewLayer displays video in conjunction with the captureSession
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.videoGravity = .resizeAspectFill
                videoPreviewLayer?.frame = view.layer.bounds
                view.layer.addSublayer(videoPreviewLayer!)
            }
            catch {
                print("CaptureSession Error")
            }
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // MARK: - AVCaptureMetadataOutputObjectsDelegate
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        syncThread {
            if metadataObjects.count == 0 {
                print("no objects returned")
                return
            }
            
            let metaDataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
            guard let StringCodeValue = metaDataObject.stringValue else {
                return
            }
            
            //transformedMetaDataObject returns layer coordinates/height/width from visual properties
            guard let _ = self.videoPreviewLayer?.transformedMetadataObject(for: metaDataObject) else {
                return
            }
            
            AudioServicesPlayAlertSound(self.systemSoundId)
            
            if let url = URL(string: StringCodeValue) {
                self.delegate?.sendURL(url: url)
            }
        }
    }
}

원하는 frame에서만 QRCode를 읽기

  • AVCaptureMetadataOutput의 rectOfInterest 속성을 이용하면 된다.
  • 그런데 해당 프레임은 직접적인 값을 주는 것이 아니라 비율을 넘겨야한다.
    • (0, 0, 1, 1) 값이 최소, 최대 값이다. 0% ~ 100%까지 프레임을 채운다.
    • (0, 0, 0.5, 0.5) 는 0% ~ 50% 까지만 프레임을 채운다는 뜻이다.
  • 주의할 점은 일반적으로 스마트폰을 사용할 때처럼 세로상태(Portrait)기준이 아니라 왼쪽으로 누운상태(Landscape Left)에서 좌측 하단이 0,0 으로 계산한다.
  • 아래 예는 Portrait 상태의 가로 절반 크기의 정 사각형의 크기로 화면 정 중앙에서만 QRCode를 읽는 예제이다.
// CaptureSession needs and output to transfer Data to
let captureMetadataOutput = AVCaptureMetadataOutput()
// frame setting
let value: CGFloat = view.frame.size.width/2
let x: CGFloat = 0.25
let y: CGFloat = (1 - value / view.frame.width) / 2
let width: CGFloat = 0.5
let height: CGFloat = value / view.frame.size.height

captureMetadataOutput.rectOfInterest = CGRect(x: y,
                                              y: 1 - x - width,
                                              width: height,
                                              height: width)
captureSession?.addOutput(captureMetadataOutput)


'Develop > iOS' 카테고리의 다른 글

[SwiftBook] 타입 1/2  (0) 2018.09.19
[SwiftBook] 값  (0) 2018.09.18
[iOS] Swift Codable  (0) 2018.09.09
[iOS] Swift 도형 그리기  (0) 2018.07.29
[iOS Developer Program] iOS 개인 개발자 등록  (0) 2018.02.26
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31