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


在用 AVFoundation 完成扫码后,遇到2个问题:

1,如何限制扫描范围?

2.条形码如何扫描?

一位朋友的文章帮助了我,特地转来,可以帮到有需要的朋友。

原文:http://www.2cto.com/kf/201411/356046.html

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

// Input

_input = [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:nil];

// Output

_output = [[AVCaptureMetadataOutputalloc]init];

[_outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

// Session

_session = [[AVCaptureSessionalloc]init];

[_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

if ([_sessioncanAddInput:self.input])

{

[_sessionaddInput:self.input];

}

if ([_sessioncanAddOutput:self.output])

{

[_sessionaddOutput:self.output];

}

//
条码类型 AVMetadataObjectTypeQRCode

_output.metadataObjectTypes [email protected][AVMetadataObjectTypeQRCode];

// Preview

_preview =[AVCaptureVideoPreviewLayerlayerWithSession:_session];

_preview.videoGravity =AVLayerVideoGravityResizeAspectFill;

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

[self.view.layerinsertSublayer:_previewatIndex:0];

// Start

[_sessionstartRunning];

然后实现 AVCaptureMetadataOutputObjectsDelegate

#pragma mark AVCaptureMetadataOutputObjectsDelegate

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

{

NSString *stringValue;

if ([metadataObjectscount] >0)

{

//停止扫描

[_sessionstopRunning];

AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex:0];

stringValue = metadataObject.stringValue;

}

}

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

vc/CzuejrLDRy/nT0M/rtb21xLe9t6i2vMrUwcvSu7Hpo6y1q8rHtryyu9DQo6i2vMrHwOGjqaOs1+66872r0qq3xcb6tcTKsbryt6LP1sHL0ru49rHIvc+/ydLJtcS146GjPC9wPgo8cD48YnI+CjwvcD4KPHA+PC9wPgo8cD5AcHJvcGVydHkobm9uYXRvbWljKUNHUmVjdCByZWN0T2ZJbnRlcmVzdApOU19BVkFJTEFCTEVfSU9TKDdfMCk7PC9wPgrV4srHtcQgQVZDYXB0dXJlTWV0YWRhdGFPdXRwdXQg0ru49sr00NSjrMv8tcS94srNyscKCjxwPgpAZGlzY3Vzc2lvbjwvcD4KPHA+ClRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGEgQ0dSZWN0IHRoYXQgZGV0ZXJtaW5lcyB0aGUgcmVjZWl2ZXI="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,

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

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

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

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

[_outputsetRectOfInterest: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 互换了吧?算了不管怎么着,试一试吧。

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

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

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

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

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

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

时间: 2024-08-26 21:22:55

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

二维码扫描(iOS原生二维码扫描)

一.关于二维码扫描的第三方库有很多:例如比较常用的两个 1.ZBar SDK ZBar为我们提供了两种使用方式,一种是直接调用ZBar提供的ZBarReaderViewController打开一个扫描界面,另一种方式是使用ZBar提供的可以嵌在其他视图中的ZBarReaderView,实际项目中我们更可能会使用第二种方式,这可以让我们对界面做更多的定制,详细的百度查找相关文档来看. 2.ZXing(Github镜像地址)是一个开源的条码生成和扫描库(开源协议为Apache2.0).它不但支持众多

iOS之二维码的制作与扫描

IOS之二维码的制作与扫描     二维码SDK的Dome“QRCode”中制作libqrencode库文件,扫描ZBarSDK库文件1.制作二维码  /*字符转二维码导入 libqrencode文件添加  #import "QRCodeGenerator.h"@property (strong , nonatomic) UIImageView* qRImageView;- (void)viewDidLoad{    [super viewDidLoad];    self.qRIma

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

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

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

在代码中使用了相对布局框架Masonry 准备两张图片,一张是扫描边框,一张是扫描时的细线分别命名 scanFrame.png和scanLine.png并提前放入工程 导入相对布局头文件 #define MAS_SHORTHAND #define MAS_SHORTHAND_GLOBALS #import "Masonry.h" 导入依赖头文件 #import <AVFoundation/AVFoundation.h> 具体代码如下: static const char *

iOS 原生二维码扫描

哎 关于限制扫码范围的控制,弄了老夫好久,还是不尽如意 .h 1 // 2 // LIUScanTwoDimensionalCode.h 3 // YouYouShoppingCenter 4 // 5 // Created by liujun on 15/7/28. 6 // Copyright (c) 2015年 刘俊. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import <AVFoundation/AVF

iOS 花式二维码生成和二维码识别

iOS 原生的二维码识别非常之棒,反正比 ZXing 和 ZBar 效果都好些,所以以后打算尽量用原生的二维码识别,然后最近把原生的二维码生成也顺便做了一遍,并且在原有基础上加了一些样式参数,封了一个小库方便以后使用. 项目地址:https://github.com/EyreFree/EFQRCode EFQRCode 是一个用 Swift 编写的用来生成和识别二维码的库,它基于系统二维码生成与识别进行开发. 生成:利用输入的水印图/图标等资源生成各种艺术二维码: 识别:识别率比 iOS 原生二

iOS之原生二维码扫描

做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以开始了. 一.做好准备工作,搭建UI IBOutlet.IBAction如下: @property (weak, nonatomic) IBOutlet UIView *vie

iOS:原生二维码扫描

做iOS的二维码扫描,有两个第三方库可以选择,ZBar和ZXing.今天要介绍的是iOS7.0后AVFoundation框架提供的原生二维码扫描. 首先需要添加AVFoundation.framework框架到你工程中build phase的"Link Binary With Libraries"之下,然后就可以开始了. 一.做好准备工作,搭建UI UI效果如图 IBOutlet.IBAction如下: @property (weak, nonatomic) IBOutlet UIVi

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

iOS开发-二维码扫描和应用跳转 序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar.使用时集成麻烦,出错也不方便调试.在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架.本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转.ps:本期的源代码会在文章结尾给出链接 扫描相关类 二维码扫描需要获取摄像头并读取