天天看点

IOS7使用原生API进行二维码和条形码的扫描

ios7之前,开发者进行扫码编程时,一般会借助第三方库。常用的是zbarsdk,ios7之后,系统的avmetadataobject类中,为我们提供了解析二维码的接口。经过测试,使用原生api扫描和处理的效率非常高,远远高于第三方库。

官方提供的接口非常简单,代码如下:

<a href="http://my.oschina.net/u/2340880/blog/405847#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<code>@interface viewcontroller ()&lt;avcapturemetadataoutputobjectsdelegate&gt;</code><code>//用于处理采集信息的代理</code>

<code>{</code>

<code>    </code><code>avcapturesession * session;</code><code>//输入输出的中间桥梁</code>

<code>}</code>

<code>@end</code>

<code>@implementation viewcontroller</code>

<code>- (</code><code>void</code><code>)viewdidload {</code>

<code>    </code><code>[super viewdidload];</code>

<code>    </code><code>// do any additional setup after loading the view, typically from a nib.</code>

<code>    </code><code>//获取摄像设备</code>

<code>    </code><code>avcapturedevice * device = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo];</code>

<code>    </code><code>//创建输入流</code>

<code>    </code><code>avcapturedeviceinput * input = [avcapturedeviceinput deviceinputwithdevice:device error:nil];</code>

<code>    </code><code>//创建输出流</code>

<code>    </code><code>avcapturemetadataoutput * output = [[avcapturemetadataoutput alloc]init];</code>

<code>    </code><code>//设置代理 在主线程里刷新</code>

<code>    </code><code>[output setmetadataobjectsdelegate:self queue:dispatch_get_main_queue()];</code>

<code>    </code> 

<code>    </code><code>//初始化链接对象</code>

<code>    </code><code>session = [[avcapturesession alloc]init];</code>

<code>    </code><code>//高质量采集率</code>

<code>    </code><code>[session setsessionpreset:avcapturesessionpresethigh];</code>

<code>    </code><code>[session addinput:input];</code>

<code>    </code><code>[session addoutput:output];</code>

<code>    </code><code>//设置扫码支持的编码格式(如下设置条形码和二维码兼容)</code>

<code>    </code><code>output.metadataobjecttypes=@[avmetadataobjecttypeqrcode,avmetadataobjecttypeean13code, avmetadataobjecttypeean8code, avmetadataobjecttypecode128code];</code>

<code>       </code> 

<code>    </code><code>avcapturevideopreviewlayer * layer = [avcapturevideopreviewlayer layerwithsession:session];</code>

<code>    </code><code>layer.videogravity=avlayervideogravityresizeaspectfill;</code>

<code>    </code><code>layer.frame=self.view.layer.bounds;</code>

<code>    </code><code>[self.view.layer insertsublayer:layer atindex:0];</code>

<code>    </code><code>//开始捕获</code>

<code>    </code><code>[session startrunning];</code>

之后我们的ui上已经可以看到摄像头捕获的内容,只要实现代理中的方法,就可以完成二维码条形码的扫描:

<code>-(</code><code>void</code><code>)captureoutput:(avcaptureoutput *)captureoutput didoutputmetadataobjects:(nsarray *)metadataobjects fromconnection:(avcaptureconnection *)connection{</code>

<code>    </code><code>if</code> <code>(metadataobjects.count&gt;0) {</code>

<code>        </code><code>//[session stoprunning];</code>

<code>        </code><code>avmetadatamachinereadablecodeobject * metadataobject = [metadataobjects objectatindex : 0 ];</code>

<code>        </code><code>//输出扫描字符串</code>

<code>        </code><code>nslog(@</code><code>"%@"</code><code>,metadataobject.stringvalue);</code>

<code>    </code><code>}</code>

通过上面的代码测试,我们可以发现系统的解析处理效率是相当的高,ios官方提供的api也确实非常强大,然而,我们可以做进一步的优化,将效率更加提高:

首先,avcapturemetadataoutput类中有一个这样的属性(在ios7.0之后可用):

@property(nonatomic) cgrect rectofinterest;

这个属性大致意思就是告诉系统它需要注意的区域,大部分app的扫码ui中都会有一个框,提醒你将条形码放入那个区域,这个属性的作用就在这里,它可以设置一个范围,只处理在这个范围内捕获到的图像的信息。如此一来,可想而知,我们代码的效率又会得到很大的提高,在使用这个属性的时候。需要几点注意:

1、这个cgrect参数和普通的rect范围不太一样,它的四个值的范围都是0-1,表示比例。

2、经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。

3、宽度和高度设置的情况也是类似。

3、举个例子如果我们想让扫描的处理区域是屏幕的下半部分,我们这样设置

<code>output.rectofinterest=cgrectmake(0.5,0,0.5, 1);</code>

具体apple为什么要设计成这样,或者是这个参数我的用法那里不对,还需要了解的朋友给个指导。

继续阅读