ios二维码条码扫描问题

原创 2017年08月09日 19:42:52

ios原生AVFoudation扫描在同时支持二维码和条码扫描时,二维码总是很快得到数据,条码则有时有有时无,在坑里待了一段时间后终于找到原因,VCaptureMetadataOutput 有一个属性 rectOfInterest



rectOfInterest

就是设置元数据识别搜索的区域。

这个属性有点问题,不是普通的CGRect,四个值都需要在0~1之间。

AVCaptureVideoPreviewLayer 有个方法 

- (CGRect)metadataOutputRectOfInterestForRect:(CGRect)rectInLayerCoordinates 

可以看看这个方法的说明:



方法说明

描述就是:把一个在previewlayer坐标系中的rect 转换成 一个在metadataoutputs坐标系中的rect。

这个方法需要的rect参数是我们系统坐标系中的rect.

SO 。这就得到了我们需要的rectOfInterest。


代码:

- (BOOL)startReading {

    NSError *error;

    

    //1.初始化捕捉设备(AVCaptureDevice),类型为AVMediaTypeVideo

    AVCaptureDevice *captureDevice = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    

    //2.captureDevice创建输入流

    AVCaptureDeviceInput *input = [AVCaptureDeviceInputdeviceInputWithDevice:captureDeviceerror:&error];

    if (!input) {

        NSLog(@"%@", [errorlocalizedDescription]);

        returnNO;

    }

    

    //3.创建媒体数据输出流

    AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutputalloc] init];

    

    //4.实例化捕捉会话

    _captureSession = [[AVCaptureSessionalloc] init];

    

    //4.1.将输入流添加到会话

    [_captureSessionaddInput:input];

    

    [_captureSessionsetSessionPreset:AVCaptureSessionPresetHigh];

    

    //4.2.将媒体输出流添加到会话中

    [_captureSessionaddOutput:captureMetadataOutput];

    

    //5.创建串行队列,并加媒体输出流添加到队列当中

    dispatch_queue_t dispatchQueue;

    //dispatchQueue = dispatch_queue_create("myQueue", NULL);

    dispatchQueue = dispatch_get_main_queue();

    //5.1.设置代理

    [captureMetadataOutput setMetadataObjectsDelegate:selfqueue:dispatchQueue];

    

    //5.2.设置输出媒体数据类型为QRCode

    [captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code]];

    

    //6.实例化预览图层

    _videoPreviewLayer = [[AVCaptureVideoPreviewLayeralloc] initWithSession:_captureSession];

    

    //7.设置预览图层填充方式

    [_videoPreviewLayersetVideoGravity:AVLayerVideoGravityResizeAspectFill];

    

    //8.设置图层的frame

    [_videoPreviewLayersetFrame:_vPreview.layer.bounds];

    

    //9.将图层添加到预览view的图层上

    [_vPreview.layeraddSublayer:_videoPreviewLayer];

    

    //10.设置扫描范围

    captureMetadataOutput.rectOfInterest =CGRectMake(0.2f,0.2f, 0.8f,0.8f);

    

    //10.1.扫描框

    _boxView = [[UIViewalloc] initWithFrame:CGRectMake(60, [[UIScreenmainScreenbounds].size.height/2 -30 -([[UIScreenmainScreenbounds].size.width - 60 * 2)/2, [[UIScreenmainScreenbounds].size.width - 60 * 2, [[UIScreenmainScreenbounds].size.width - 60 * 2)];

    _boxView.layer.borderColor =mainColor.CGColor;

    _boxView.layer.borderWidth =1.0f;

    [_vPreviewaddSubview:_boxView];

    

    //10.2.扫描线

    _scanLayer = [[CALayeralloc] init];

    _scanLayer.frame =CGRectMake(0,0, _boxView.bounds.size.width,1);

    _scanLayer.backgroundColor = [UIColorcolorWithRed:190.0/255green:190.0/255blue:190.0/255alpha:1.0].CGColor;

    [_boxView.layeraddSublayer:_scanLayer];

    

    NSTimer *timer = [NSTimerscheduledTimerWithTimeInterval:0.2ftarget:selfselector:@selector(moveScanLayer:)userInfo:nilrepeats:YES];

    [timer fire];

    

    //放大焦距

    [captureDevice lockForConfiguration:&error];

    

    if (captureDevice.activeFormat.videoMaxZoomFactor > 2) {

        captureDevice.videoZoomFactor =2;

    }else{

        captureDevice.videoZoomFactor = captureDevice.activeFormat.videoMaxZoomFactor;

    }

    [captureDevice unlockForConfiguration];

    

    //10.开始扫描

    [_captureSessionstartRunning];

    

    //11.必须在startRunning之后才会生效(坑哦)

    CGRect rect =CGRectMake(30,100, self.view.frame.size.width - 60, 300);

    CGRect intertRect = [_videoPreviewLayermetadataOutputRectOfInterestForRect:rect];

    CGRect layerRect = [_videoPreviewLayerrectForMetadataOutputRectOfInterest:intertRect];

    

    NSLog(@"%@,  %@",NSStringFromCGRect(intertRect),NSStringFromCGRect(layerRect));

    

    captureMetadataOutput.rectOfInterest = intertRect;

    

//    这种方法实际不可行

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

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

//    

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

    

    returnYES;

}


第11步就是解决方法,指定新的rectOfInterest给captureMetadataOutput,之后扫条码和二维码就都可以啦




版权声明:本文为博主原创文章,未经博主允许不得转载。

python安装及开发IDE安装配置

python安装 mac系统其实自带了一个python的执行执行环境,用来运行python还行,但是开发可能就不够了,因此我们需要重新安装python。这里有两种方案安装: 1.homebrew ...

iOS开发证书发布证书,推送证书,描述文件的生成总集

一.开发证书发布证书制作 进入  (Launchpad),找到   (我的是在其他里面找到的),运行后再左上角                          存储在桌面就好了,然后就完成退出钥匙...

iOS - 二维码、条码扫描

iOS7.0后AVFoundation框架提供的原生二维码、条码扫描。#import "ViewController.h" @interface ViewController ()@property ...

条码扫描二维码扫描—ZXing android 改进版本

1、增加了将代码嵌套入自己工程后传值的办法(初学,如果有更好的方法也希望告诉我,先谢谢了) 2、扫码界面进行了处理(初步实现了现有某些软件的样子,至于长的像谁就不说了) ...

android 二维码及条码扫描

  • 2013年09月13日 09:51
  • 982KB
  • 下载

条码扫描&二维码

  • 2014年12月23日 12:39
  • 28.5MB
  • 下载

如何在代码里区分条码扫描扫描到是是一维码还二维码

以前没有搞过二维码,最近遇到一个问题,如何判断条码扫描扫描到的是一维码还是二维码,这下可把我吓到了,说实话这个还真不知道,经过几个小时的艰苦奋斗,终于让我解决了,也许方法有很多种,或许并不是只有我这一...

二维码or条码扫描

  • 2016年01月25日 15:57
  • 404KB
  • 下载

条码扫描二维码扫描——ZXing android 源码简化

前言   最近公司的Android项目需要用到摄像头做条码或二维码的扫描,Google一下,发现一个以Apache License 2.0 开源的 ZXing项目。Zxing项目里的Android实...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ios二维码条码扫描问题
举报原因:
原因补充:

(最多只允许输入30个字)