嘿嘿,小编我又来了!😉
今天要给大家说的是利用系统自带的AVFoundation和CoreImage框架来完成二维码的制作和扫描
从iOS7开始苹果为了让自己更加牛逼,就集成了二维码的生成和扫描,二维码的内容不仅包含传统的纯数字,含包括了纯文本,URL还有就是名片.我的天啦感觉真的苹果好厉害啊,那么现在就开始武装自己,让自己变得厉害起来吧.
首先我们先来讲述制作二维码的步骤和相关代码!
第一步:导入框架#import <CoreImage/CoreImage.h>
为了保证生成二维码的同时,保证主线程的操作,所以我在这里创建了一个单独的线程去完成二维码的生成.前面我对GCD已经做出了讲述而且git上有比较全面的demo,大多是swift版的也有OC版的代码,大家如果对这方面还不太熟悉可以去看一下,并且上面有自己写的PPT.希望大家能够喜欢.废话就说到这吧,开始代码的展示:
创建用于生成二维码的队列有些人肯定在哪里看到过类似的代码,比如AFNetworking中队列的创建也是这么写的,但是我这多了一个修饰词inline,有很多人可能知道这个关键字修饰函数的意思是什么,但是有些人肯定不知道,在这里简单说一下,inline修饰的函数叫做内联函数,我们普通函数的调用,在汇编一层来讲,都会在正式执行方法之前,先将函数现场保存起来,然后调用calll方法后去执行我们的函数和方法,等执行完毕后,在回复函数现场,继续执行下面的操作.举个简单例子吧:比如在控制器内部,我们阿紫viewdidload中调用了本类的setUpData方法,去准备数据源.这个过程就是先将viewDidLoad的函数现场保存起来,然后汇编一层回到用call方法,再将setUpData通过运行时机制发消息给控制器,等方法执行完成时,在回复viewDidLoad的函数现场,继续下面的显示数据等方法.这就是普通函数的调用,那么内联函数到底是怎么回事啦,内联函数,不会保存函数现场,而是在执行该函数时,将该函数的函数体部分作为调用函数的一部分融入到调用函数中.因此进行内联型函数调用时,不需要保留现场,也不会产生控制权转移.会减少一部分的时间消耗.
上面那个是内联函数:在给大家举个内联函数的例子吧.在YYKit中有这样一段代码:
//C函数
CGFloatYYScreenScale() {
staticCGFloatscale;
staticdispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
scale = [UIScreenmainScreen].scale;
});
returnscale;
}
//内联函数
static inlineCGFloatCGFloatFromPixel(CGFloat value) {
returnvalue/YYScreenScale();
}
但是使用内联函数时有很多需要注意的点我给大家总结为下面几点:
1.内联函数只是我们向编译器提供的申请,编译器不一定采取inline形式调用函数.
2.内联函数不能承载大量的代码.如果内联函数的函数体过大,编译器会自动放弃内联.
3.内联函数内不允许使用循环语句或开关语句.
4.内联函数的定义须在调用之前.
怎么跑题了,好了回归正题吧.
先看这段代码:
CIFilter这段代码的主要步骤是1.创建过滤器,2.将过滤器恢复默认3.为过滤器设置数据4.获取生成的二维码.
5.因为生成的二维码比较模糊,所以我们要将这个图片进行加工来返回一个高清的二维码.
生成高清二维码先看CGRectIntegral这个函数在NSHiper上的解释是:返回包围源矩形的最小整数矩形.
将CGRect取整到最近的完整点是非常重要的。小数值会让边框画在像素边界处。因为像素已经是最小单元(不能再细分),小数值会使绘制时取周围几个像素的平均值,这样看起来就模糊了.所以这个函数就是取整.
然后计算宽高德比例.计算bitmap先是计算宽高size_t是计算机中无符号类型.创建一个CGColorSpaceRef(颜色空间)具体请看苹果官方文档,CGColorSpaceCreateDeviceGray()这个函数是创建一个灰度空间.CGContextRef是用来绘图的.CIContext:它与Core Graphics和OpenGL中使用的context很是类似,所有有关Core Image的处理流程都是通过它来进行完成的;然后看到了我们比较熟悉的CGImageRef终于到了生成图片了,我的天啦好兴奋啊.在刚才生成的上下文中创建CGImageRef.CGContextSetInterpolationQuality允许上下文在各个保真度等级插入像素。在这里我第二个参数传递的是None,还有其他供大家选择请看下面官方文档中的解释:
CGInterpolationQuality下一步:缩放坐标系然后就是将图片会知道上下文中.最后获取到上下文中图片.然后将生成的高清二维码图片返回.
制作就讲到着了后面会将demo传到github上.大家可以自行学习.
下来说一下扫描二维码:
首先也是创建专门的队列用于扫描类似上面制作的代码类似.
然后是导入AVFoundation框架.
扫描二维码第一步:创建捕捉会话.
第二步:添加设备(数据是从摄像头输入)
第三步:添加输出设备(示例对象-类对象-元类对象-根元类对象)
第四步:设置<AVCaptureMetadataOutputObjectsDelegate>代理对象和输入元数据的类型(类型是二维码数据)
第5步:添加扫描图层,添加扫描图层到传进来的视图layer上.
第六步:开始扫描
然后是实现代理方法:
代理方法当扫描到结果也就是metadataObjects的个数大于0时,表示扫描到了数据,然后将数据利用block传出.然后关掉扫描并且移除扫描图层.
如果错误可以自行做出错误处理.
demo地址https://github.com/Vickeywei/WQRqCode
使用方法在viewController中有使用方法.
如果以后大家有什么文章希望能够分享在我的专题之下目前文章较少,关注人也比较少,但是日积月累吗!总会好起来的.专题是:iOS学习引擎
谢谢
本人联系方式:qq:513961360
email:513961360@qq.com
也可以加我们的qq群希望能与朋友们一起聊天和学习.群里还有很多iOS开发者,帮助我们解决问题,并且同时学习.
qq群号:580284575
网友评论