1.问题:同时设置支持二维码和条码的时候,扫条码识别不准确。
如: NSArray *arr = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
为了正确解释这个有趣的问题,我们要解释一下条形码扫描原理。
上面有提过二维码是通过全局直方图二值化后,按照ISO标准解碼,实际上是,按照1:1:3:1:1去寻找那三个寻像图形,就是标志性的大方块。然后圈出二维码大小再去解碼的。也就是说,再没设定边界的情况下全屏都可以。
而条形码完全不同,他是在Detect Center那个点,画一个无限延伸的米字型,然后去判断每一条在线能否解析出条形码所需要的0101010序列。而iOS默认的Center是 Layer 的 Center。
我们再回过头来看工程中的 SurfaceLayer,其实他提示给用户的那个框,已经远离了Center。所以我们竖着扫描的时候,那条水平的扫描线是没有贯穿条形码的,所以扫不上他。
解决办法:设置原生 rectOfInterest扫描区域
//大致意思是设置每一帧画面感兴趣的区域 也就是扫描范围的设置 默认为左上角 (0,0,1,1)这是默认值 全屏的 最大为1
//经实践发现 (0,0,,1,1)这个写法有点坑 实际为(y,x,h,w) 即坐标y,x 尺寸高,宽(h,w)
//下面代码是我设置的扫描区域
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input) return;
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
// 扫描区域
CGSize size = self.view.bounds.size;
CGRect cropRect = CGRectMake(SCREEN_WIDTH/2-110,100,220,220);
output.rectOfInterest = CGRectMake(cropRect.origin.y/SCREEN_HEIGHT,
cropRect.origin.x/size.width,
cropRect.size.height/size.height,
cropRect.size.width/size.width);
参考了如下:
https://www.cnblogs.com/allen123/p/4519188.html
https://blog.csdn.net/lixianyue1991/article/details/70894982
如果想直接用二维码扫描,这里推荐一个库比较齐全:
A barcode and qr code scanner (二维码、扫码、扫一扫、ZXing、ZBar、iOS系统AVFoundation扫码封装,扫码界面效果封装)
https://github.com/MxABC/LBXScan