AVFoundation二维码扫描限制区域

写这篇文章的主要原因不是展示如何使用  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 deviceproviding 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 )];

又扫描了一下发现成功了!果然原点正确了,我只想说TMD!

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

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

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

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

今天就跟大家分享这一个点,转载请注明出处,谢谢 — — LC

时间: 2024-07-30 13:13:25

AVFoundation二维码扫描限制区域的相关文章

Swift AVFoundation 二维码扫描和生成

项目最终不须要支持iOS6了(泪崩),在二维码扫描这一块,可以全然的放弃ZXing库,改用系统的AVFoundation了,拿swift写了个Demo,效果例如以下: github地址:点这里 有关AVFoundation和Core Image(滤镜等),可以先看看objc.io第21期和第23期的有关介绍. 初始化视频捕捉 // 初始化视频捕获 private func initCapture() { // 代表抽象的硬件设备,这里传入video let captureDevice = AVC

浅谈iOS7 AVFoundation 二维码扫描

iOS7,AVFoundation中现在已经内置支持一维和二维码的扫瞄,iOS6及之前的想要扫瞄二维码,还是需要添加第三方库ZXing和ZBar.ZBar生成二维码:http://blog.csdn.net/cafei111/article/details/8924297先添加AVFoundation.framework#import <AVFoundation/AVFoundation.h>@interface QRcodeViewController :UIViewController&l

Swift:使用系统AVFoundation实现二维码扫描和生成

系统提供的AVCaptureSession仅仅适用于iOS7.0以上的系统.之前的请用Zbar来替代 下载地址:http://download.csdn.net/detail/huobanbengkui/8881097 配置project: 引入: import Foundation import AVFoundation 接受AVCaptureMetadataOutputObjectsDelegate(如: class QrcodeVC: UIViewController,AVCaptureM

iOS 系统二维码扫描(可限制扫描区域)

使用 AVFoundation系统库来进行二维码扫描并且限制扫描二维码的范围.(因为默认的是全屏扫描) -(void)beginCode { //1.摄像头设备 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; /* // Media types AVMediaTypeVideo AVMediaTypeAudio AVMediaTypeText AVMediaTypeC

iOS 原生二维码扫描(可限制扫描区域)

写这篇文章的主要原因不是展示如何使用 AVFoundation   来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了苹果原生的扫描. 原生的好处就是扫描特别快效率特别高,但是遇到一个问题就是不知道怎么去限制扫描范围. 还是先简单说一下怎么使用来进行二维码扫描吧. 首先是要用到的几个类 @property (strong,nonatomic)AVCaptureDevice * device; @propert

苹果原生二维码扫描功能——可限制扫描区域

使用原生的好处就是扫描特别快效率特别高,使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(默认的是全屏扫描) 首先是要用到的几个类 @property ( strong , nonatomic ) AVCaptureDevice * device; @property ( strong , nonatomic ) AVCaptureDeviceInput * input; @property ( strong , nonatomic ) AVCaptureMe

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

在用 AVFoundation 完成扫码后,遇到2个问题: 1,如何限制扫描范围? 2.条形码如何扫描? 一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友. 原文:http://www.2cto.com/kf/201411/356046.html 写这篇文章的主要原因不是展示如何使用 AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了苹果原生的扫描. 原生的好处就是扫描特别快效

iOS使用AVFoundation实现二维码扫描

实现过程如下: Step1:需要导入:AVFoundation Framework 包含头文件: #import <AVFoundation/AVFoundation.h> Step2:设置捕获会话 设置 AVCaptureSession 和 AVCaptureVideoPreviewLayer 成员 1 2 3 4 5 6 7 8 9 10 #import <AVFoundation/AVFoundation.h> static const char *kScanQRCodeQu

【转】 iOS使用AVFoundation实现二维码扫描

原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应介绍也非常多,如:http://rdcworld-iphone.blogspot.in/2013/03/how-to-use-barcode-scanner-br-and-qr-in.html ZXing google推出的开源项目,相应介绍如:http://blog.devtang.com/blo