美文网首页程序员@产品@IT·互联网
iOS swift版 原生相机/相册图片的二维码识别,添加闪光灯

iOS swift版 原生相机/相册图片的二维码识别,添加闪光灯

作者: this帅气的名字 | 来源:发表于2017-04-28 08:10 被阅读0次

    现今我们的生活已经离不开了二维码了,无论是出行、购物、吃饭、娱乐等等都伴随着二维码的身影,二维码让我们的生活更便利,品质更高。人们出行只需要带上一部手机就可以完成几乎所有的需求,这就要提到关于二维码的扫描识别了。
    通过swift学习后,写了一个小demo,以本文来记录一下原生二维码的扫描识别。

    效果图如下:

    相机二维码扫描.gif
    相册图片二维码识别.gif
    demo地址在:https://github.com/ZZtimegoesby/ZZScanQRcode

    1. 原生二维码扫描

    iOS7之后AVFoundation提供了原生二维码扫描的功能,无论是在扫描灵敏度上还是性能上来说与之前的zbar和zxing等三方库相比都是最优的,所以对二维码的扫描识别开发用苹果原生是最好的,但是只限于是iOS7+系统。

    1.1 二维码扫描需要的类:

    二维码扫描需要导入AVFoundation框架import AVFoundation。需要用到一下5个类:

    • AVCaptureDevice 获取设备类
    • AVCuptureSession 绘画对象类,承担实时获取设备数据的任务。
    • AVCuptureDeviceInput 设备输入类。
    • AVCaptureMetadataOutput 设备输出类,支持二维码、条形码等图像数据的识别。
    • AVCaptureVideoPreviewLayer 图层类,可以快速呈现摄像头采集的原始数据。

    通过以上5个类可以实现摄像头对二维码的扫描识别。

    1.2 二维码扫描:

    1)创建设备会话对象,用来配置设备的输入输出。

     //创建会话对象  承担实时获取设备数据的责任
      session = AVCaptureSession.init()
      session.sessionPreset = AVCaptureSessionPresetHigh //设置高质量采集
    

    2)遵守AVCaptureMetadataOutputObjectsDelegate协议,获取手机摄像头设备作为输入设备,创建输出类,设置代理delegate、有效的扫描区域和可识别的图像类型metadataObjectTypes,将其添加到会话对象session中。

    //获取手机摄像头
    device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)      
    //设备输入类
    let input = try! AVCaptureDeviceInput.init(device: device)
    //设备输出类    支持二维码、条形码的扫描识别
    output = AVCaptureMetadataOutput.init()
    //设置
    output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            
    //将输入、输出对象加入到会话中
    session.addInput(input)
    session.addOutput(output)
            
    //只能在执行完上一步之后才能执行设置可识别数据的格式
    output.metadataObjectTypes = [AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]
    //设置有效的扫描区域  注意:坐标系原点为右顶点,横为y,竖为x
    output.rectOfInterest = CGRect(x: (height - scanWidth - 64)/2/height, y: (width - scanWidth)/2/width, width: scanWidth, height: scanWidth)
    

    *注意:rectOfInterest(有效扫描范围)的坐标系有所不同,屏幕右上角为坐标原点,左上角位(0,1),左下角为(1,1),右下角为(1,0)。
    3)创建图层类previewlayer,实时获取摄像头数据并显示在屏幕上。

    //创建图层类  可以快速呈现摄像头的原始数据
    previewlayer = AVCaptureVideoPreviewLayer.init(session: session)
    previewlayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    previewlayer?.frame = self.view.frame
    self.view.layer.insertSublayer(previewlayer!, at: 0)
    

    4)设置协议回调方法,当扫描到二维码/条形码时会触发代理方法,对得到的数据进行处理。

    //扫描到二维码时调用
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
            
         if metadataObjects.count > 0 {
             //获取二维码数据对象
             let metadata: AVMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
            }
        }
    

    以上就是关于手机相机二维码图像扫描的相关配置。

    2. 相册中图片二维码的识别

    1)需要用到UIImagePickerController类得到手机相册控制器,所以首先需要导入imageIO框架import imageIO,遵守两个协议UIImagePickerControllerDelegateUINavigationControllerDelegate,模态跳转到手机相册。

    //创建相册控制器
    let imagepicker = UIImagePickerController()
    imagepicker.delegate = self
    self.present(imagepicker, animated: true, completion: nil)
    

    2)配置协议回调方法,一个是当选择相册图片后会触发,一个是当点击取消后会触发。

        //点击图片时触发该方法
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
            //获取点击图片
            let image = info[UIImagePickerControllerOriginalImage] as! UIImage
            
            //.....获取采集的二维码数据....//
            
            self.dismiss(animated: true) {
                //数据处理
            }
        }
        //点击取消时调用该方法
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            self.dismiss(animated: true, completion: nil)
        }
    

    3)得到相册的图片后,利用扫描仪CIDetector类对图片上的二维码进行识别,获取二维码上的数据message

    //创建图片扫描仪
    let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
    //获取到二维码数据
    let featureArr = detector?.features(in: CIImage.init(cgImage: image.cgImage!))
    let feature = featureArr?.first as! CIQRCodeFeature //二维码图像特征
    let message = feature.messageString!
    

    以上完成了对手机相册图片二维码的识别。

    3. 添加闪光灯及添加提示音

    在demo中我还添加了开关闪光灯及添加提示音的功能。提示音需要用到AudioToolbox框架`import AudioToolbox。

    var soundID: SystemSoundID = 0
    let soundFile = Bundle.main.path(forResource: "scanSound", ofType: "wav")
    //生成系统声音
    AudioServicesCreateSystemSoundID(NSURL.fileURL(withPath: soundFile!) as  CFURL, &soundID)
     //播放提示音 带有震动
    //      AudioServicesPlayAlertSound(soundID)
     //播放系统提示
     AudioServicesPlaySystemSound(soundID)
    

    闪光灯用上文的device就可以了,实现较简单在这里就不一一写出来了。如果需要可以去下载demo来学习,我还没有封装成库,之后会改进,也欢迎给我提出一些demo的问题,我会去一一解决。能star一下最好了,谢谢了!!

    二维码扫描识别集成demo地址:https://github.com/ZZtimegoesby/ZZScanQRcode
    参考文章:http://www.jianshu.com/p/4772d3cb6a43

    相关文章

      网友评论

        本文标题:iOS swift版 原生相机/相册图片的二维码识别,添加闪光灯

        本文链接:https://www.haomeiwen.com/subject/axenzttx.html