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

现今我们的生活已经离不开了二维码了,无论是出行、购物、吃饭、娱乐等等都伴随着二维码的身影,二维码让我们的生活更便利,品质更高。人们出行只需要带上一部手机就可以完成几乎所有的需求,这就要提到关于二维码的扫描识别了。
通过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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容