swift学习小计(扫描二维码)

基于swift3.0

1.创建设备

//MARK: 绘画
    lazy var session: AVCaptureSession = {
        let ss = AVCaptureSession()
        return ss
    }()
    //MARK: 设备
    lazy var device: AVCaptureDevice = {
        let dev = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        return dev!
    }()
    //MARK: 输入设备
    lazy var deviceInput: AVCaptureDeviceInput? = {
        
        do {
            let input = try AVCaptureDeviceInput(device: self.device)
            return input
        }catch {
            print(error)
            return nil
        }
        
    }()
    //MARK: 输出设备
    lazy var deviceOutput: AVCaptureMetadataOutput = {
        let metaOut = AVCaptureMetadataOutput()
       /* metaOut.metadataObjectTypes = metaOut.availableMetadataObjectTypes
        metaOut.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 
         这两句不能写在
         session.addInput(deviceInput)
         session.addOutput(deviceOutput)
         之前
         */
        return metaOut
    }()

2.创建扫描边框

//MARK: 边框
    lazy var imageView: UIImageView = {
        let imgView = UIImageView(image: UIImage(named: "qrcode_border"))
        imgView.frame.origin.x = (self.view.frame.width - 200) * 0.5
        imgView.frame.origin.y = 200
        imgView.frame.size = CGSize(width: 200, height: 200)
        return imgView
    }()

3.添加扫描线和扫描线的动画

lazy var scanLine: UIImageView = {
        let lineImageView = UIImageView(image: UIImage(named: "QRCode_ScanLine"))
        lineImageView.frame = CGRect(x: self.imageView.frame.origin.x, y: self.imageView.frame.origin.y, width: self.imageView.frame.size.width, height: 2)
        return lineImageView
    }()
    func scanAnimation() -> CABasicAnimation {
        let startPoint = CGPoint(x: self.scanLine.center.x, y: self.imageView.frame.origin.y)
        let endPoint = CGPoint(x: self.imageView.center.x, y: self.imageView.frame.maxY - 2)
        
        
        let animation = CABasicAnimation(keyPath: "position")
        animation.fromValue = NSValue(cgPoint: startPoint)
        animation.toValue = NSValue(cgPoint: endPoint)
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        animation.duration = 1
        animation.autoreverses = true
        animation.repeatCount = 10000
        return animation
    }

4.添加预览图层

//MARK: 预览图层
    lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer?.frame = UIScreen.main.bounds
        return layer!
    }()

5.开始扫描

func startScan() -> Void {
        if !session.canAddInput(deviceInput) {
            return
        }
        if !session.canAddOutput(deviceOutput) {
        return
        }
        scanLine.layer.add(scanAnimation(), forKey: "haha")
        session.addInput(deviceInput)
        session.addOutput(deviceOutput)
        deviceOutput.metadataObjectTypes = deviceOutput.availableMetadataObjectTypes
        deviceOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        //设置扫面区域
        deviceOutput.rectOfInterest = (previewLayer.metadataOutputRectOfInterest(for: self.imageView.frame))
        session.startRunning()
        
    }
 override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        title = "扫描二维码"
        view.addSubview(imageView)
        view.addSubview(scanLine)
        view.layer.insertSublayer(previewLayer, at: 0)
        startScan()
    }

6.扫面完成后的代理(没仔细处理)

extension QRCodeViewController : AVCaptureMetadataOutputObjectsDelegate {
    public func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
//        [corners { 0.6,0.8 0.9,0.8 0.9,0.2 0.6,0.2 }, time 149347505505458, stringValue "http://weixin.qq.com/r/ydlCWn3EqSDWrTk594zb"]
        if metadataObjects == nil || metadataObjects.count == 0 {
        return
        }
        for object in metadataObjects {
            if object is AVMetadataMachineReadableCodeObject {
                let metadataObj = metadataObjects.last as! AVMetadataMachineReadableCodeObject
//                print(metadataObj.corners)
                
                let pointS : AVMetadataMachineReadableCodeObject = previewLayer.transformedMetadataObject(for: metadataObj) as! AVMetadataMachineReadableCodeObject
                drawCorners(codeObject: pointS)
            }
        }

    }
    private func drawCorners(codeObject: AVMetadataMachineReadableCodeObject) {
        clearSubView()
        let layer = CAShapeLayer()
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = UIColor.red.cgColor
        let pointDic  = codeObject.corners
//        let poindArr = CGPoint.init(dictionaryRepresentation: pointDic)
        let aa = pointDic![0] as! NSDictionary
        let point0 = CGPoint.init(dictionaryRepresentation: aa)
        
        let bb = pointDic![1] as! NSDictionary
        let point1 = CGPoint.init(dictionaryRepresentation: bb)
        
        let cc = pointDic![2] as! NSDictionary
        let point2 = CGPoint.init(dictionaryRepresentation: cc)
        
        let dd = pointDic![3] as! NSDictionary
        let point3 = CGPoint.init(dictionaryRepresentation: dd)
        
    
        
        let path = UIBezierPath()
        path.move(to: point0!)
        path.addLine(to: point1!)
        path.addLine(to: point2!)
        path.addLine(to: point3!)
        path.close()
        layer.path = path.cgPath
        drawLayer.addSublayer(layer)

    }
    func clearSubView() -> Void {
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0{
            return
        }
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}

你可能感兴趣的:(swift学习小计(扫描二维码))