关于iOS二维码扫描焦距及位置

    对于开发人员,即便资深老前辈也可能会出现没用过而短时间内解决不了的问题。今天我就遇到过求助了好几个大神都没能解决。而且在网上找了半天才找到。

先说下情况:公司三年老项目看着好坏参半的代码头疼的事就不说了。目前公司需求是二维码扫描效果不是很好,主要就是焦距问题。让我以微信作为参考。以前我也没去注意到,打开微信扫一扫的同时打开了我们项目的扫一扫对比了下结果

关于iOS二维码扫描焦距及位置_第1张图片

以下是设置相机单独抽出来的代码

- (void)setupCamera

{

captureDevice= [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];// Device

captureInput= [AVCaptureDeviceInputdeviceInputWithDevice:captureDeviceerror:nil];// Input

captureOutput= [[AVCaptureMetadataOutputalloc]init];// Output

[captureOutputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

captureSession= [[AVCaptureSessionalloc]init];// Session

[captureSessionsetSessionPreset:AVCaptureSessionPresetHigh];

if([captureSessioncanAddInput:captureInput])

{

[captureSessionaddInput:captureInput];

}

if([captureSessioncanAddOutput:captureOutput])

{

[captureSessionaddOutput:captureOutput];

}

//条码类型AVMetadataObjectTypeQRCode

captureOutput.metadataObjectTypes=@[

AVMetadataObjectTypeQRCode,

AVMetadataObjectTypeUPCECode,

AVMetadataObjectTypeEAN8Code,

AVMetadataObjectTypeEAN13Code,

AVMetadataObjectTypeAztecCode,

AVMetadataObjectTypeCode39Code,

AVMetadataObjectTypeCode93Code,

AVMetadataObjectTypePDF417Code,

AVMetadataObjectTypeCode128Code,

AVMetadataObjectTypeCode39Mod43Code,

];

dispatch_async(dispatch_get_main_queue(), ^{

//更新界面

capturePreview=[AVCaptureVideoPreviewLayerlayerWithSession:captureSession];

capturePreview.videoGravity=AVLayerVideoGravityResizeAspectFill;

capturePreview.frame=self.view.bounds;

// Start

[captureSessionstartRunning];

});

}

此时只需要将试图layer层放大就可以完成效果:

[capturePreviewsetAffineTransform:CGAffineTransformMakeScale(1.5,1.5)];

需注意代码的顺序。给layer层设置frame的代码后放大。否则你会看到漆黑一片。

关于iOS二维码扫描焦距及位置_第2张图片

(后期插入补充):这段是测试人员发现的bug,由于上面将相机可视的layer层放大后导致超出控制器的view。此时在处理完扫描事件结果会退出当前扫描控制器。仔细看会发现控制器退出时卡在一半零点几秒后再完全退出。(与之前的版本进行对比)。此时修剪下capturePreview就行:

self.view.clipsToBounds=YES;

self.view.layer.masksToBounds=YES;

另一个问题:当你变形放大展示的layer层后二维码在可视界面之外也是可以进行扫描获取,于是乎我了解到将layer层的变大但是执行任务还是以整个layer大小来扫描执行。需要设置一个属性setRectOfInterest,他是摄像中AVCaptureMetadataOutput类的一个属性,他是通过一个CGRect来设置,但是有两点:1、它是横屏情况下的frame所以宽高和XY值需反向操作。就是按照竖屏模式应该将原先是XYWH要改为YXHW来设置。2、它是一个比例值以00开始为原点最大比例宽高为11(既全屏扫描情况下CGRect的写法为(0,0,1,1))。而且最大比例不是以手机尺寸比例,而是由capturePreview这个layer层为总比例。这也说明了为什么你能扫描超出屏幕尺寸外的二维码信息内容。

此处的scanCropRect接收了上面已设置好的中间扫描框的frame

CGFloat scanCropRectX = (capturePreview.frame.size.height - scanCropRect.size.height)/2;

CGFloat scanCropRectY = (capturePreview.frame.size.width - scanCropRect.size.width)/2;

//调整扫描位置

[captureOutputsetRectOfInterest:CGRectMake( scanCropRectX,scanCropRectY,scanCropRect.size.height/ capturePreview.frame.size.height ,scanCropRect.size.width/ capturePreview.frame.size.width )];

终于解决了扫描位置的问题

你可能感兴趣的:(关于iOS二维码扫描焦距及位置)