篇文章的主要原因不是展示如何使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围。(因为默认的是全屏扫描)

项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了苹果原生的扫描。

原生的好处就是扫描特别快效率特别高,但是遇到一个问题就是不知道怎么去限制扫描范围。

还是先简单说一下怎么使用来进行二维码扫描吧。

首先是要用到的几个类

@property ( strong , nonatomic ) AVCaptureDevice * device;

@property ( strong , nonatomic ) AVCaptureDeviceInput * input;

@property ( strong , nonatomic ) AVCaptureMetadataOutput * output;

@property ( strong , nonatomic ) AVCaptureSession * session;

@property ( strong , nonatomic ) AVCaptureVideoPreviewLayer * preview;

他们之间的关系可以看下面的篇文章

传送门

下面分别创建他们

// Device

_device = [ AVCaptureDevice defaultDeviceWithMediaType : AVMediaTypeVideo ];

// Input

_input = [ AVCaptureDeviceInput deviceInputWithDevice : self . device error : nil ];

// Output

_output = [[ AVCaptureMetadataOutput alloc ] init ];

[ _output setMetadataObjectsDelegate : self queue : dispatch_get_main_queue ()];

// Session

_session = [[ AVCaptureSession alloc ] init ];

[ _session setSessionPreset : AVCaptureSessionPresetHigh ];

if ([ _session canAddInput : self . input ])

{

[ _session addInput : self . input ];

}

if ([ _session canAddOutput : self . output ])

{

[ _session addOutput : self . output ];

}

// 条码类型 AVMetadataObjectTypeQRCode

_output . metadataObjectTypes = @[ AVMetadataObjectTypeQRCode ] ;

// Preview

_preview =[ AVCaptureVideoPreviewLayer layerWithSession : _session ];

_preview . videoGravity = AVLayerVideoGravityResizeAspectFill ;

_preview . frame = self . view . layer . bounds ;

[ self . view . layer insertSublayer : _preview atIndex : 0 ];

// Start

[ _session startRunning ];

然后实现 AVCaptureMetadataOutputObjectsDelegate

#pragma mark AVCaptureMetadataOutputObjectsDelegate

- ( void )captureOutput:( AVCaptureOutput *)captureOutput didOutputMetadataObjects:( NSArray *)metadataObjects fromConnection:( AVCaptureConnection *)connection

{

NSString *stringValue;

if ([metadataObjects count ] > 0 )

{

// 停止扫描

[ _session stopRunning ];

AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];

stringValue = metadataObject. stringValue ;

}

}

到此为止就可以成功扫描二维码了,但是有个尴尬的问题,这时的扫描是全屏扫描的。即

一般情况下项目中的扫描页面是这样的,但是当你扫描的时候会发现在二维码还没进入中心的那个小方块时,就已经成功扫描完成了,这对于体验来说很不好。但是由于那时候赶项目就没有时间优化。终于今天抽出来时间了。

我从早上上班开始一直搞到下午,把所有想到的方法都试了一遍,但是都不行(都是泪),最后将要放弃的时候发现了一个比较可疑的点。

@property ( nonatomic ) CGRect rectOfInterest NS_AVAILABLE_IOS ( 7 _0);

这是的  AVCaptureMetadataOutput 一个属性,它的解释是

@discussion

The value of this property is a CGRect that determines the receiver's rectangle of interest for each frame of video.

The rectangle's origin is top left and is relative to the coordinate space of the device providing the metadata.  Specifying

a rectOfInterest may improve detection performance for certain types of metadata. The default value of this property is the

value CGRectMake(0, 0, 1, 1).  Metadata objects whose bounds do not intersect with the rectOfInterest will not be returned.

大概意思就是设置每一帧画面感兴趣的区域(字面意思),那岂不是就是设置扫描范围喽,大喜

于是赶紧把 rectOfInterest 设置成中间框的frame,

[ _output setRectOfInterest : CGRectMake (( ScreenWidth - 220 )/ 2 , 60 + 64 , 220, 220 )];

//中间区域的宽和高都是220   ScreenWidth为设备屏幕宽度

但是却发现怎么扫描都不能成功了。于是又看了看上面的一段话。

第二句:区域的原点在左上方(后面才知道坑苦我了!),然后区域是相对于设备的大小的,默认值是 CGRectMake(0, 0, 1, 1) ,这时候我才知道是有比例关系的,最大值才是1,也就是说只要除以相应的设备宽和高的大小不就行了?然后就改成

[ _output setRectOfInterest : CGRectMake ((( ScreenWidth - 220 )/ 2 )/ScreenWidth ,( 60 + 64 )/ ScreenHigh , 220 / ScreenWidth , 220 / ScreenHigh )];

按说这样应该就完美了,但是才知道我还是高兴得太早了,一扫描才发现完全不是那么回事,差很多。

于是我就一点一点调,但是最后也没调成功,最后一狠心有设置了一个很确定的值。

[ _output   setRectOfInterest : CGRectMake ( 0.5 , 0.5 , 0.5 ,  0.5 )];

这次应该很确定是在右下方的四分之一区域吧,嘿嘿。

但是事实又一次打击了我,扫描后发现是左下的四分之一区域,也就是说 rectOfInterest的原点是右上角!!!

回头又一想,即使右上角是原点那也应该没有影响啊,但是为什么不行呢,不会是原点的 X 和 Y 互换了吧?算了不管怎么着,试一试吧。

[ _output setRectOfInterest : CGRectMake (( 60 + 64 )/ ScreenHigh ,(( ScreenWidth - 220 )/ 2 )/ ScreenWidth , 220 / ScreenWidth , 220 / ScreenHigh )];

又扫描了一下发现成功了!果然原点正确了。

转载说明出处。

但是宽和高又怎么对不上了?不会也互换了吧!赶紧试试

[ _output setRectOfInterest : CGRectMake (( 124 )/ ScreenHigh ,(( ScreenWidth -220 )/ 2 )/ ScreenWidth , 220 / ScreenHigh , 220 / ScreenWidth )];

怀着忐忑的心情又试了试,完美扫描!OMG我想死的心都有了。

于是用系统原生的扫描二维码就完美了

iOS 原生二维码扫描(可限制扫描区域)的更多相关文章

  1. iOS 原生二维码扫描和生成

    代码地址如下:http://www.demodashi.com/demo/12551.html 一.效果预览: 功能描述:WSLNativeScanTool是在利用原生API的条件下封装的二维码扫描工 ...

  2. iOS系统原生 二维码的生成、扫描和读取(高清、彩色)

    由于近期工作中遇到了个需求:需要将一些固定的字段 在多个移动端进行相互传输,所以就想到了 二维码 这个神奇的东东! 现在的大街上.连个摊煎饼的大妈 都有自己的二维码来让大家进行扫码支付.可见现在的二维 ...

  3. 【转】 iOS 原生二维码扫描(可限制扫描区域)

    在用 AVFoundation 完成扫码后,遇到2个问题: 1,如何限制扫描范围? 2.条形码如何扫描? 一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友. 原文:http://blog.csd ...

  4. iOS 原生二维码扫描,带扫描框和扫描过程动画

    在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #defin ...

  5. iOS:原生二维码扫描

    做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framewo ...

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

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

  7. Firemonkey 原生二维码扫描优化

    之前用了ZXing的Delphi版本,运行自带的例子,速度非常慢,与安卓版本的相比查了很多,因此打算使用集成jar的方法,但是总觉得美中不足. 经过一番研究,基本上解决了问题. 主要有两方面的优化: ...

  8. iOS - QRCode 二维码

    1.QRCode 在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing. 这两大组件我们都有用过,这里总结下各自的缺点: 1.ZBar 在扫描 ...

  9. IOS开发 二维码功能的实现

    原帖地址:http://yul100887.blog.163.com/blog/static/20033613520121020611299/ 如今二维码随处可见,无论是实物商品还是各种礼券都少不了二 ...

随机推荐

  1. Java中类Exchaner浅析

    Exchaner用于实现两个人之间的数据交换,每个人在完成一定的事物后想与对方交换数据,第一个先拿出数据的人将一直等待第二个人拿着数据到来时,才能彼此交换数据. 张孝祥老师在讲解Exchaner时的比 ...

  2. poj1150

    这道题告诉我们递推一定要慢慢细细的推Pmn=n!/m!,我们可以先考虑n!的最后一位是什么首先最后一位非0位我们首先想到把0都干掉也就是先把2和5提出来,这两个其实是同样的方法对于N!中有多少个因数2 ...

  3. Node.js权威指南 (3) - Node.js基础知识

    3.1 Node.js中的控制台 / 19 3.1.1 console.log方法 / 19 3.1.2 console.error方法 / 20 3.1.3 console.dir方法 / 21 3 ...

  4. Light OJ 1031 - Easy Game(区间DP)

    题目大意: 给你一个n,代表n个数字,现在有两个选手,选手A,B轮流有有一次机会,每个选手一次可以得到一个或者多个数字,从左侧或者右侧,但是不能同时从两边取数字,当所有的数字被取完,那么游戏结束.然后 ...

  5. Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍

    磁盘分区表.文件系统的查看.统计的工具很多,有些工具是多功能的,不仅仅是查看磁盘的分区表,而且也能进行磁盘分区的操作:但在本文,我们只讲磁盘分区的查看,以及分区的使用情况的查看:本文只是给新手上路之用 ...

  6. C/S结构与B/S结构的特点分析

    C/S结构与B/S结构的特点分析 为了区别于传统的C/S模式,才特意将其称为B/S模式.认识到这些结构的特征,对于系统的选型而言是很关键的. 1.系统的性能 在系统的性能方面,B/S占有优势的是其异地 ...

  7. AOP Aspect Oriented Programming

    原理AOP(Aspect Oriented Programming),也就是面向方面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP将应用系统分为两部分,核心业务逻辑(Core bus ...

  8. java 泛型学习

    http://blog.csdn.net/archie2010/article/details/6232228 学习集合框架的时候经常用hasmap<Integer,Integer>就是泛 ...

  9. bzoj 2819 Nim(BIT,dfs序,LCA)

    2819: Nim Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1596  Solved: 597[Submit][Status][Discuss] ...

  10. CSS3 概览 更新时间 2014-0412-1317

    CSS3 概览 CSS3可以划分为:文字.边框模型.背景.动画等. CSS3颜色模块 CSS2.1的时候可以使用4种颜色方式,直接使用颜色名,如 redRGB值,如 rgb(0,90,255)RGB百 ...