iOS原生实现二维码扫描

  最近项目上需要开发扫描二维码进行签到的功能,主要用于开会签到的场景,所以为了避免作弊,我们再开发时只采用直接扫描的方式,并且要屏蔽从相册读取图片,此外还在二维码扫描成功签到时后台会自动上传用户的当前地点,如何自动定位获取用户的当前地点在上一篇随笔iOS学习——自动定位中已经讲过了,本文就简单地说一下如何利用iOS原生的模块实现二维码的扫描。

  二维码扫描是很多应用都会实现的功能,比较著名的第三方开源库是Google出品的ZXing,其的OC的移植版本是ZXingObjc。iOS系统原生的二维码扫描模块是在iOS7之后推出的,它主要是利用iOS设备的后置摄像头进行实现的。

  要调用系统的摄像头识别二维码,我们需要导入系统的AVFoundation库。使用系统的摄像头,我们一般的需要以下五个对象:一个后置摄像头设备(AVCaptureDevice)、一个输入(AVCaptureDeviceInput)、一个输出(AVCaptureMetadataOutput)、一个协调控制器(AVCaptureSession)、一个预览层(AVCaptureVideoPreviewLayer),此外为了更好的体验效果,我们加入了缩放手势,在进行二维码扫描的时候可以手动进行缩放扫描区域,以获得更好的扫描效果。

@interface CJScanQRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate>@property (strong, nonatomic) AVCaptureDevice * device; //捕获设备,默认后置摄像头
@property (strong, nonatomic) AVCaptureDeviceInput * input; //输入设备
@property (strong, nonatomic) AVCaptureMetadataOutput * output;//输出设备,需要指定他的输出类型及扫描范围
@property (strong, nonatomic) AVCaptureSession * session; //AVFoundation框架捕获类的中心枢纽,协调输入输出设备以获得数据
@property (strong, nonatomic) AVCaptureVideoPreviewLayer * previewLayer;//展示捕获图像的图层,是CALayer的子类@property (strong, nonatomic) UIPinchGestureRecognizer *pinchGes;//缩放手势
@property (assign, nonatomic) CGFloat scanRegion_W;//二维码正方形扫描区域的宽度,根据不同机型适配@end

  首先,我们是需要进行对我们的一些设备进行配置,比喻需要用到自动定位,就需要对定位信息进行配置,接着对二维码扫描的相关设备进行配置,然后对我们的缩放手势进行设置,都配置完之后,直接开始启动二维码扫描就可以了,成功扫码并识别到信息时候会调用对应的 AVCaptureMetadataOutputObjectsDelegate 代理的 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection 方法进行后期处理,我们需要实现代理的该方法,在其中编写我们需要的功能逻辑。

- (void)viewDidLoad {[super viewDidLoad];//页面标题self.title = @"扫一扫";//配置定位信息[self configLocation];//配置二维码扫描[self configBasicDevice];//配置缩放手势[self configPinchGes];//开始启动[self.session startRunning];
}

  关于二维码扫描设备的配置流程,一般地,我们先将需要的五大设备进行初始化,然后需要进行对应的设置没具体的设置流程和方法见下面的代码和注释。

- (void)configBasicDevice{//默认使用后置摄像头进行扫描,使用AVMediaTypeVideo表示视频self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];//设备输入 初始化self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];//设备输出 初始化,并设置代理和回调,当设备扫描到数据时通过该代理输出队列,一般输出队列都设置为主队列,也是设置了回调方法执行所在的队列环境self.output = [[AVCaptureMetadataOutput alloc]init];[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];//会话 初始化,通过 会话 连接设备的 输入 输出,并设置采样质量为 高self.session = [[AVCaptureSession alloc]init];[self.session setSessionPreset:AVCaptureSessionPresetHigh];//会话添加设备的 输入 输出,建立连接if ([self.session canAddInput:self.input]) {[self.session addInput:self.input];}if ([self.session canAddOutput:self.output]) {[self.session addOutput:self.output];}//指定设备的识别类型 这里只指定二维码识别这一种类型 AVMetadataObjectTypeQRCode//指定识别类型这一步一定要在输出添加到会话之后,否则设备的课识别类型会为空,程序会出现崩溃[self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];//设置扫描信息的识别区域,本文设置正中央的一块正方形区域,该区域宽度是scanRegion_W//这里考虑了导航栏的高度,所以计算有点麻烦,识别区域越小识别效率越高,所以不设置整个屏幕CGFloat navH = self.navigationController.navigationBar.bounds.size.height;CGFloat viewH = ZYAppHeight - navH;CGFloat scanViewH = self.scanRegion_W;[self.output setRectOfInterest:CGRectMake((ZYAppWidth-scanViewH)/(2*ZYAppWidth), (viewH-scanViewH)/(2*viewH), scanViewH/ZYAppWidth, scanViewH/viewH)];//预览层 初始化,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示//预览层的区域设置为整个屏幕,这样可以方便我们进行移动二维码到扫描区域,在上面我们已经对我们的扫描区域进行了相应的设置self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];self.previewLayer.frame = CGRectMake(0, 0, ZYAppWidth, ZYAppHeight);self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;[self.view.layer addSublayer:self.previewLayer];//扫描框 和扫描线的布局和设置,模拟正在扫描的过程,这一块加不加不影响我们的效果,只是起一个直观的作用TNWCameraScanView *clearView = [[TNWCameraScanView alloc]initWithFrame:self.view.frame navH:navH];[self.view addSubview:clearView];//扫描框下面的信息label布局UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, (viewH+scanViewH)/2+10.0f, ZYAppWidth, 20.0f)];label.text = @"扫一扫功能仅用于会议签到";label.font = FONT(15.0f);label.textColor = [UIColor whiteColor];label.textAlignment = NSTextAlignmentCenter;[self.view addSubview:label];
}

  接下来我们看一下如何配置我们的缩放手势,这个相对而言就很简单了,我们直接在self.view上添加一个缩放手势,并在对应的方法中对我们的相机设备的焦距进行修改就达到了缩放的目的。

- (void)configPinchGes{self.pinchGes = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchDetected:)];[self.view addGestureRecognizer:self.pinchGes];
}- (void)pinchDetected:(UIPinchGestureRecognizer*)recogniser{if (!_device){return;}//对手势的状态进行判断if (recogniser.state == UIGestureRecognizerStateBegan){_initScale = _device.videoZoomFactor;}//相机设备在改变某些参数前必须先锁定,直到改变结束才能解锁NSError *error = nil;[_device lockForConfiguration:&error]; //锁定相机设备if (!error) {CGFloat zoomFactor; //缩放因子CGFloat scale = recogniser.scale;if (scale < 1.0f) {zoomFactor = self.initScale - pow(self.device.activeFormat.videoMaxZoomFactor, 1.0f - recogniser.scale);} else {zoomFactor = self.initScale + pow(self.device.activeFormat.videoMaxZoomFactor, (recogniser.scale - 1.0f) / 2.0f);}zoomFactor = MIN(15.0f, zoomFactor);zoomFactor = MAX(1.0f, zoomFactor);_device.videoZoomFactor = zoomFactor;[_device unlockForConfiguration];}
} 

  最后,我们需要重写代理的回调方法,实现我们在成功识别二维码之后要实现的功能逻辑。这样我们的二维码扫描功能就完成了。

#pragma mark - AVCaptureMetadataOutputObjectsDelegate
//后置摄像头扫描到二维码的信息
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{[self.session stopRunning];   //停止扫描if ([metadataObjects count] >= 1) {//数组中包含的都是AVMetadataMachineReadableCodeObject 类型的对象,该对象中包含解码后的数据AVMetadataMachineReadableCodeObject *qrObject = [metadataObjects lastObject];//拿到扫描内容在这里进行个性化处理NSString *result = qrObject.stringValue;//解析数据进行处理并实现相应的逻辑//代码省略
}

转载于:https://www.cnblogs.com/HHD-9199/p/8567218.html

iOS原生实现二维码扫描相关推荐

  1. iOS 自带二维码扫描功能的实现

    #自从iOS7以后中新增了二维码扫描功能.因此可以在不借助第三方类库的情况下简单的写出二维码的扫描功能: 原生的二维码扫描功能在AVFoundation框架下,所以在使用原生的二维码扫描功能时要先导入 ...

  2. iOS原生封装二维码、条形码扫描工具;生成、识别(彩色)二维码、条形码图片

    二维码扫描在App中很常见的功能,之前都是用三方工具Zing.ZBar.后来Apple的AVFoundation也支持二维码扫描.生成,而且效率比三方库还要高.我把它封装成一个工具,这样使用起来十分方 ...

  3. 如何给iOS应用添加原生的二维码扫描功能

    之前总觉得二维码扫描很高大上,其实apple工程师早就为我们提供了便捷的方法.二维码扫描第三方的库也挺多的,不过效率高的当属系统提供的扫描方法. 二维码扫描主要用到了以下几个类: AVCaptureD ...

  4. iOS原生实现二维码拉近放大

    http://www.cocoachina.com/ios/20180416/23033.html 2018-04-16 15:34 编辑: yyuuzhu 分类:iOS开发 来源:程序鹅 8 300 ...

  5. ios客户端学习-二维码扫描和应用跳转

    转载至链接:http://sindrilin.com/ios-dev/2015/11/01/二维码扫描和应用跳转.html 序言 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  6. iOS AV Foundation 二维码扫描 02 扫码

    AVFoundation支持以下一维和二维码的扫描: QR code Aztec EAN13 EAN8 UPC-E PDF417 Code 93 Code 39 Code 39 mode 41 QR ...

  7. iOS:源生二维码扫描和制作

    MMScanner:iOS源生二维码扫描和制作工具,轻量级UI,UI也可根据属性自行修改.支持条形码扫描以及识别图片中的二维码,制作二维码可以指定颜色.大小.可嵌入logo. 使用 pod " ...

  8. 在IOS上实现二维码扫描

    如今二维码随处可见,无论是实物商品还是各种礼券都少不了二维码的身影.而手机等移动设备又成为二维码的一个很好的应用平台,不管是生成二维码还是扫码二维码. 下面介绍一下如何在苹果iOS设备上使用二维码: ...

  9. IOS --自带二维码扫描

    2019独角兽企业重金招聘Python工程师标准>>> 具体的可以参考这篇文章:http://www.appcoda.com/qr-code-ios-programming-tuto ...

最新文章

  1. 用Unity和C#创建在线多人游戏学习教程
  2. ue查找多个关键字_聊聊数据库GROUP BY关键字的那些事
  3. Django 模板中使用css, javascript
  4. 别克gl8服务器返回数据为空,老司机教学:别克GL8商务车总线控制系统故障解决...
  5. skypebridge.exe 损坏的映像 错误代码 0xc000012f
  6. 服务器显示A40故障码,奔驰E400L仪表显示“主动车道保持系统停止运作”
  7. 计算机桌面出现临时文件,tmp什么文件,为什么出现tmp文件
  8. 生活娱乐 如何像印度人学英语
  9. aName:array[0..31] of WideChar;//编译提示检测到错误类EAccessViolation//没有初始化
  10. 如何用Python制作简单又好看的词云?来瞅瞅吧~
  11. 不符合python命名规则的是_下面不符合Python语言命名规则的是__________。
  12. STM32【复习串口】
  13. go-stat-reporter(1):golang开发通用报表展示系统,设计数据结构
  14. 学习java的第17天
  15. 密室逃脱(二)碧绿色房间
  16. “香约宁波”寻觅城市文化味
  17. 自学软件测试,第一份外包工作8K,到现在大厂月薪30K*16薪
  18. linux美化软件,Linux 桌面美化
  19. android引导页图片全屏适配,关于图片适配不同尺寸的image View(实战)
  20. 苹果自带相册打马赛克_做电子相册不用第三方工具!直接用手机自带的功能

热门文章

  1. 教你如何在@ViewChild查询之前获取ViewContainerRef
  2. 前端面试题-CSS选择器性能优化
  3. Git与GitHub学习笔记(六)使用 Github Pages 管理项目文档
  4. 数据结构探险之图篇(上)理论篇
  5. OK335x mksd.sh hacking
  6. 是男人就下100层【第五层】——2048游戏从源码到发布市场
  7. 我来做百科(第一天)
  8. 福师离线 微型计算机与外部,福师《计算机应用基础》离线作业答案
  9. gulp : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\gulp.ps1,因为在此系统上禁止运行脚本
  10. python学习方法_十二种学习Python的方法