准备工作

  1. 导入<CoreImage/CoreImage.h>,生成二维码用
  2. 导入<AVFoundation/AVFoundation.h>,读取二维码用
  3. 设置代理协议AVCaptureMetadataOutputObjectsDelegate,这是有关摄像设备输出的相关代理

注意:扫描二维码的时候,要在info.plist文件中添加字段,否则会崩溃(iOS10之后的隐私权限问题)

<!-- 相册 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>App需要您的同意,才能访问相册</string>
<!-- 相机 -->
<key>NSCameraUsageDescription</key>
<string>App需要您的同意,才能访问相机</string>

二维码的生成

1.生成二维码的步骤:

1.导入CoreImage框架
2.通过滤镜CIFilter生成二维码

2.代码如下

调用下方根据字符串生成二维码的方法即可获得二维码// 生成二维码
- (UIImage *)createImageWithString:(NSString *)string{// 1.实例化二维码滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 2.恢复滤镜的默认属性(因为滤镜可能保存上一次的属性)
[filter setDefaults];// 3.讲字符串转换为NSData
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];*// 4.通过KVO设置滤镜inputMessage数据
[filter setValue:data forKey:@"inputMessage"];// 5.通过了滤镜输出的图像
CIImage *outputImage = [filter outputImage];// 6.因为生成的二维码模糊,所以通过createNonInterpolatedUIImageFormCIImage:outputImage来获得高清的二维码图片UIImage *image = [self getErWeiMaImageFormCIImage:outputImage withSize:200];return image;
}
// 获取高清二维码图片
- (UIImage *)getErWeiMaImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));// 1.创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);// 2.保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}

二维码的扫描

1.读取二维码的步骤:

1.读取二维码需要导入AVFoundation框架(上方准备工作的时候已经说了)
2.利用相机识别二维码中的内容(只能是真机)
3.会话将相机采集到的二维码图像转换成字符串数据

2.原生扫描中用到的几个类

AVCaptureDevice                        // 拍摄设备
AVCaptureDeviceInput                   // 输入设备
AVCaptureMetadataOutput                // 元数据输出
AVCaptureSession                       // 拍摄会话
AVCaptureVideoPreviewLayer             // 视频预览图层

3.代码如下

- (void)readQRCode{// 1.实例化拍摄装备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];// 2.设置输入设备
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];// 3.设置元数据输出
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];   // 设置代理// 4.添加拍摄会话
self.session = [[AVCaptureSession alloc] init];
[self.session addInput:input];       // 添加会话输入
[self.session addOutput:output];     // 添加会话输出[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];      // 设置输出数据类型(需要将元数据输出添加到会话后才能制定元数据类型,否则会报错)// 5.视频预览图层
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; // 传递session是为了告诉图层将来显示什么内容
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;   // 显示方式
// 设置videoGravity,顾名思义就是视频播放时的拉伸方式,默认是AVLayerVideoGravityResizeAspect
// AVLayerVideoGravityResizeAspect 保持视频的宽高比并使播放内容自动适应播放窗口的大小。
// AVLayerVideoGravityResizeAspectFill 和前者类似,但它是以播放内容填充而不是适应播放窗口的大小。最后一个值会拉伸播放内容以适应播放窗口.
// 因为考虑到全屏显示以及设备自适应,这里我们采用fill填充self.previewLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:self.previewLayer atIndex:0]; // 将图层插入当前图层// 6.启动会话
[self.session startRunning];
}
AVCaptureMetadataOutputObjectsDelegate 的代理方法
/**扫描结果处理 @param captureOutput 输出数据源
 @param metadataObjects 扫描结果数组
 @param connection 用于协调输入与输出之间的数据流*/
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{// 1.判断扫描结果的数据是否存在
if ([metadataObjects count] > 0) {// 2.如果存在数据,则停止会话[self.session stopRunning];// 3.删除预览图层[self.previewLayer removeFromSuperlayer];AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0];// AVMetadataMachineReadableCodeObject 是AVMetadataObject的具体子类定义的特性检测一维或二维条形码。// AVMetadataMachineReadableCodeObject代表一个单一的照片中发现机器可读的代码。这是一个不可变对象描述条码的特性和载荷。// 在支持的平台上,AVCaptureMetadataOutput输出检测机器可读的代码对象的数组NSString *stringValue = metadataObject.stringValue;if ([stringValue containsString:@"http"]) {// 如果是字符串,则打开连接[[UIApplication sharedApplication] openURL:[NSURL URLWithString:stringValue] options:[NSDictionary dictionary] completionHandler:^(BOOL success) {if (success) {NSLog(@"成功");}}];}else{NSLog(@"普通字符串:%@",stringValue);     // 可以将字符串放到需要用到的地方(比如label)}}}

传送门:https://github.com/yangchao970093824/CreateAndReadQRCode

iOS开发二维码生成和扫描相关推荐

  1. iOS 开发 二维码生成大全(黑白/彩色二维码和带图片的二维码)详解

    前言 扫描二维码使用的是coreImage框架,属于UIKit框架中的体系,多以使用时不用导入coreImage框架 开始之前,让我们谈谈Core Image框架中最重要的几个类: CIContext ...

  2. iOS开发二维码生成(一)

    二维码是一种比一维码更高级的条码格式.一维码只能在一个方向(一般是水平方向)上表达信息,而二维码在水平和垂直方向都可以存储信息.一维码只能由数字和字母组成,而二维码能存储汉字.数字和图片等信息,因此二 ...

  3. iOS 之 二维码生成与扫描(LBXScan)

    参考:https://github.com/MxABC/LBXScan 步骤如下: 1. 下载 通过参考网址进行下载. 2. 导入 导入整个LBXScan文件夹 3. 配置 在pch中加入 #impo ...

  4. iOS开发-二维码扫描和应用跳转

    iOS开发-二维码扫描和应用跳转   序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  5. iOS开发—二维码扫描-郭宏志-专题视频课程

    iOS开发-二维码扫描-3869人已学习 课程介绍         本课程由扣丁学堂教学总监郭宏志老师讲授,主要讲解了iOS开发专题中的二维码扫描这一专题,内容包含了二维码扫描中的全部知识,让学员更多 ...

  6. Android开发——Android中的二维码生成与扫描

    0. 前言 今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描.本篇旨在帮助有需求的同学快速完成二维 ...

  7. 微信公众平台----带参数二维码生成和扫描事件

    原文:微信公众平台----带参数二维码生成和扫描事件 摘要: 账号管理----生成带参数的二维码 消息管理----接收消息----接收事件推送 为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众 ...

  8. 苹果原生二维码生成与扫描及生成的二维码不清楚的解决方案

    苹果原生二维码生成与扫描及生成的二维码不清楚的解决方案 参考文章: (1)苹果原生二维码生成与扫描及生成的二维码不清楚的解决方案 (2)https://www.cnblogs.com/CoderEYL ...

  9. 二维码生成、扫描、图片识别(Zxing)

    这样的例子虽然已经很多了,不过我在网上浏览了一圈,也没找到几个图库二维码图片识别例子,好的算法识别率才高.这里有一个好点的算法,算法不是我写的,只是作为整理记录,给众多安卓开发者一个方便.demo的U ...

最新文章

  1. 最小化局部边际的合并聚类算法(中篇)
  2. asp.net 2.0中的弹出对话框
  3. 究竟是该采用面向服务结构,还是单体结构
  4. 图像篡改痕迹检测:Adobe双流Faster R-CNN网络
  5. UPS不断电割接流程和步骤
  6. QT4 自定义槽和信号
  7. hide show vue 动画_Vue2.x学习四:过渡动画
  8. 排序算法之选择法排序(C/C++)
  9. 8.0强行转换后变成了7_血糖7至8正常吗?控制标准不能一概而论,看你的血糖应该在多少...
  10. 计算机密码学奖,上海交通大学计算机科学与工程系(CSE)
  11. MySQL一主二从复制环境切换主从库
  12. Layer/jquery获取父窗口的元素
  13. webpack5学习与实战-(十三)-postcss处理css3兼容性前缀
  14. 2020年最新人事管理软件排名(建议收藏)!
  15. Python菜鸟教程
  16. 一文了解DataStore(Preferences)
  17. Windows Ready Boost,使用闪存设备提高性能
  18. 用Python分析《都挺好》中的人物关系
  19. 培养学生计算机绘画水平,谈电脑绘画对高校绘画教学的作用
  20. 知道一点怎么设直线方程_已知两点坐标怎样求直线方程

热门文章

  1. java dozer_java – Dozer双向映射(String,String)与自定义转换器不可能?
  2. IPV6到IPV4的转换
  3. 计算机控制系统康波课后答案,计算机控制系统(康波)第8章部分习题参考解答[1]...
  4. SEO每天都是动态变化的,你要关注什么?
  5. 打开Flutter动画的另一种姿势——Flare,android面试题选择题
  6. 解决锁定图层后不能淡显的问题
  7. python遇到错误跳过_python跳过错误
  8. css如何设置背景颜色透明?css设置背景颜色透明度的两种方法介绍
  9. 12306 抢票,极限并发带来的思考
  10. 你会心动吗?ICPR 2018 MTWI挑战赛开启