ios开发原生的扫描二维码的实现以及限制扫描区域rectOfInterest遇到的一些坑

早前面试的时候被问到扫描使用的是什么 脱口而出用的Zbar ,然后就问为何不用原生的,效率更高啊,话说刚开始干那时候只求实现,不求效率,也不知怎么的回答。现在回想,最好的回答就是: 需要相册扫描,原生的实现不了啊。

ZBar 优点: 可以实现相册相片扫描 但是效率有点低.

原生的: 效率高,但是不能做相册扫描.

下面放代码

做了些许优化

主要体现在,首次进入扫一扫vc 启动扫一扫的代码放在了

-(void)viewDidAppear:(BOOL)animated ,便于先进入在启动,不会给人卡的感觉.然后进入这个页面设置背景为黑色,当扫一扫启动ok的时候在把 背景设备为白色, 也有的在等待的时间内给他一个等待动画.

ios开发设置rectOfInterest不管用

接下来说的就是扫一扫区域限制的问题

首先属性大家基本都知道

AVCaptureMetadataOutput 的对象的属性 rectOfInterest

output.rectOfInterest=CGRectMake(100/height, (width/2 -110)/width, 220/height, 220/width);//width指的是AVCaptureVideoPreviewLayer 对象的宽度   height指的是AVCaptureVideoPreviewLayer 对象的高度

//CGRectMake(y/deviceHeight, x/deviceWidth, height/deviceHeight, width/deviceWidth);

解释下CGRectMake写法:都把x y width height 互换 了的.你扫一扫的那个框框的  起点坐标为 x  y 宽为width 高为height  ,deviceHeight ,deviceWidth指的是AVCaptureVideoPreviewLayer对象的高度但是写的时候如上,经过多次测试所得数据.大部分的宽度跟高度是相等的,但是在这里的比例是不相等的, 因为手机宽高不等. 好了接下来直接上代码.解释的不到位的就结合代码看吧.

//.h

#import <UIKit/UIKit.h>

@interface ScanCodeViewController : UIViewController

@property(nonatomic,strong)NSString *frameWhere;

@property(strong,nonatomic)void(^getSysString)(NSString*);

@end

//.m

#import "ScanCodeViewController.h"

#import <AVFoundation/AVFoundation.h>

#define widthMainControl [UIScreen mainScreen].bounds.size.width

#define heightMainControl [UIScreen mainScreen].bounds.size.height

#define colorMainBG [UIColor colorWithRed:253/255.0 green:199/255.0 blue:117/255.0 alpha:1]

@interface ScanCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>

{

AVCaptureSession * session;//输入输出的中间桥梁

int  startY;

int topHeight;

BOOL onceScan;

}

@property (strong, nonatomic) UIImageView *lineImg;

@property(nonatomic,strong)NSTimer *scanLineTimer;

@end

@implementation ScanCodeViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.title = @"扫一扫";

self.view.backgroundColor = [UIColor blackColor];

onceScan = YES;

int screenHeigth = (int)(heightMainControl);

topHeight = 100;

if (screenHeigth == 480) {

topHeight = 50;

}else if (screenHeigth == 568){

topHeight = 60;

}

}

-(void)makeUI

{

self.view.backgroundColor = [UIColor whiteColor];

UIImageView *kaungImg = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2 -110, topHeight, 220, 220)];

kaungImg.image = [UIImage imageNamed:@"sys-k"];

[self.view addSubview:kaungImg];

self.lineImg = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2 -100, topHeight + 10, 200, 7)];

self.lineImg.image = [UIImage imageNamed:@"sys-ht"];

[self.view addSubview:self.lineImg];

for (int i=0 ; i< 4; i++) {

UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(widthMainControl/2 - 110, 0, widthMainControl/2 - 110, 100)];

if (i == 0) {

leftView.frame = CGRectMake(0, 0, widthMainControl/2 - 110, heightMainControl - 64 + 64);

}else if (i == 1){

leftView.frame = CGRectMake(widthMainControl/2 - 110, 0, 220, topHeight);

}else if (i == 2){

leftView.frame = CGRectMake(widthMainControl/2 - 110 + 220, 0, widthMainControl/2 - 110, heightMainControl - 64 + 64);

}else if (i == 3){

leftView.frame = CGRectMake(widthMainControl/2 - 110, topHeight + 220, 220, heightMainControl - 64 - 220 - topHeight + 64);

}

leftView.backgroundColor = [UIColor blackColor];

leftView.alpha = 0.4;

[self.view addSubview:leftView];

}

//手动输入设备Id的按钮

UIButton *hangBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[hangBtn setTitle:@"取消" forState:UIControlStateNormal];

hangBtn.frame = CGRectMake(self.view.frame.size.width/2 -110, topHeight + 270, 220, 40);

[hangBtn addTarget:self action:@selector(pushToNextVC) forControlEvents:UIControlEventTouchUpInside];

hangBtn.layer.cornerRadius = 5;

[hangBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

hangBtn.layer.masksToBounds = YES;

hangBtn.backgroundColor = colorMainBG;

[self.view addSubview:hangBtn];

[self createTimer];

}

-(void)pushToNextVC

{

[self dismissViewControllerAnimated:YES completion:nil];

//    AddDeviceByHandViewController *addDevice = [[AddDeviceByHandViewController alloc] init];

//    [self.navigationController pushViewController:addDevice animated:YES];

}

-(void)viewDidAppear:(BOOL)animated

{

[UIView animateWithDuration:0.3 animations:^{

self.view.backgroundColor = [UIColor whiteColor];

}];

//获取摄像设备

AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

//创建输入流

AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];

//创建输出流

AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];

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

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

float width = self.view.frame.size.width;// AVCaptureVideoPreviewLayer的对象的宽度

float height = self.view.frame.size.height;// AVCaptureVideoPreviewLayer的对象的高度

output.rectOfInterest=CGRectMake(100/height, (width/2 -110)/width, 220/height, 220/width);

//CGRectMake(y, x, height, width);

//初始化链接对象

session = [[AVCaptureSession alloc]init];

//高质量采集率

[session setSessionPreset:AVCaptureSessionPresetHigh];

[session addInput:input];

[session addOutput:output];

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

[email protected][AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];

AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:session];

layer.videoGravity=AVLayerVideoGravityResizeAspectFill;

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

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

//开始捕获

[session startRunning];

[self makeUI];

}

#define LINE_SCAN_TIME  0.01     // 扫描线从上到下扫描所历时间(s)

- (void)createTimer {

startY = 110 ;

self.scanLineTimer =

[NSTimer scheduledTimerWithTimeInterval:LINE_SCAN_TIME

target:self

selector:@selector(moveScanImg)

userInfo:nil

repeats:YES];

}

-(void)moveScanImg

{

int  startX = self.view.frame.size.width/2 -100;

startY += 1;

if (startY > topHeight + 210) {

startY = topHeight + 10;

}

self.lineImg.frame = CGRectMake(startX,startY , 200, 7);

}

-(void)viewDidDisappear:(BOOL)animated

{

[self.scanLineTimer invalidate];

}

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

if (metadataObjects.count>0) {

//[session stopRunning];

AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];

//输出扫描字符串

NSLog(@"result:%@",metadataObject.stringValue);

[self dismissViewControllerAnimated:YES completion:^{

self.getSysString(metadataObject.stringValue);

}];

}

}

进入这个界面之前的页面获得扫一扫的数据

pushScan.getSysString = ^(NSString *str){

startConnectStr = str;

if (str) {

//str 就是得到的数据

//这里可以在扫一扫之后得到数据做点需要干的

}

};

全文完毕,谢谢查看.

时间: 2024-08-10 07:36:46

ios开发原生的扫描二维码的实现以及限制扫描区域rectOfInterest遇到的一些坑的相关文章

ios开发日记13-原生二维码的扫描和生成

今天博主有一个二维码扫描和生成的需求,遇到了一些困难点,在此和大家分享,希望能够共同进步. 从iOS7开始官方集成了二维码的扫描和生成功能 此前被广泛使用的zbarsdk目前不支持64位处理器 1.扫描二维码 扫描二维码需要导入AVFoundation框架 利用摄像头识别二维码中的内容(模拟器不行) 输入(摄像头) 由会话将摄像头采集到的二维码图像转换成字符串数据 输出(数据) 由预览图层显示扫描场景 // 实例化拍摄设备 AVCaptureDevice *device = [AVCapture

IOS开发技巧快速生成二维码

随着移动互联网的发展,二维码应用非常普遍,各大商场,饭店,水果店 基本都有二维码的身影,那么ios中怎么生成二维码呢? 下面的的程序演示了快速生成二维码的方法: 在ios里面要生成二维码,需要借助一个框架:#import <CoreImage/CoreImage.h>  所有首先我们需要在我们的项目中引入这个框架 下面是核心代码: 准备工作:首先在storyboard里面添加一个UIImageView 然后脱线 到控制器里面 起名为imageView 然后再控制器的viewDidload里面写

iOS开发——生成条形码,二维码

- (void)viewDidLoad { [super viewDidLoad]; self.imageView.image = [self generateBarCode:@"1524829417" width:60 height:60]; self.imageView2.image = [self generateQRCode:@"1524829417" width:60 height:60]; } - (UIImage *)generateQRCode:(N

如何用IOS原生API扫描二维码

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

ios开发之----扫描二维码、条形码

1.搭建扫描二维码的界面.可采用storyboard来搭建 2.创建对象的控制器类来管理二维码的扫描 3.在这个类中导入 #import <AVFoundation/AVFoundation.h> 框架 4.在viewDidLoad中调用 1 [self setUpQrcode]; 5.实现上面的方法 - (void)setUpQrcode { // 1.获取输入设备 AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWi

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

使用IOS7原生API进行二维码条形码的扫描 IOS7之前,开发者进行扫码编程时,一般会借助第三方库.常用的是ZBarSDK,IOS7之后,系统的AVMetadataObject类中,为我们提供了解析二维码的接口.经过测试,使用原生API扫描和处理的效率非常高,远远高于第三方库. 一.使用方法示例 官方提供的接口非常简单,代码如下: ? 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

iOS中 扫描二维码/生成二维码详解 韩俊强的博客

最近大家总是问我有没有关于二维码的demo,为了满足大家的需求,特此研究了一番,希望能帮到大家! 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 指示根视图: self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[SecondViewController new]]; 每日更新关注:http://weibo.com/hanjunqi

Android开发——通过扫描二维码,打开或者下载Android应用

Android开发——通过扫描二维码,打开或者下载Android应用 在实现这个功能的时候,被不同的浏览器折磨的胃疼,最后实现了勉强能用,也查考了一下其他人的博客 android实现通过浏览器点击链接打开本地应用(APP)并拿到浏览器传递的数据 android/iPhone:如何从browser直接打开应用程序或者打开应用商店(如果没有应用程序) 1.Html页面(JS不在行,这个是其他人写的) 需要留意的是Android_URL,格式需要符合[scheme]://[host]/[path]?[

制作IOS企业版App网页扫描二维码下载安装

有时候我们需要在XX网站的主页上去扫描二维码下载,那么ios开发中如何做到这一点呢. 我给大家解答一下,这也是在最近工作中用到的部分,在网上了解了一些. 下面给大家分解一下步骤: 1.Plist 和 IPA文件 App打包我就不细说了,这个网上教程一大堆,记得真机下打包.(Xcode->Product->Archive->Export)导出ipa文件即可. Plist文件要自己创建一个(名字你喜欢就好).格式如下:(PLIST utf-8格式) 配置plist文件 , 基于下面的模版创建