? ? 對(duì)于開發(fā)人員空入,即便資深老前輩也可能會(huì)出現(xiàn)沒用過而短時(shí)間內(nèi)解決不了的問題族檬。今天我就遇到過求助了好幾個(gè)大神都沒能解決化戳。而且在網(wǎng)上找了半天才找到点楼。
先說下情況:公司三年老項(xiàng)目看著好壞參半的代碼頭疼的事就不說了。目前公司需求是二維碼掃描效果不是很好换怖,主要就是焦距問題蟀瞧。讓我以微信作為參考。以前我也沒去注意到铸屉,打開微信掃一掃的同時(shí)打開了我們項(xiàng)目的掃一掃對(duì)比了下結(jié)果
以下是設(shè)置相機(jī)單獨(dú)抽出來的代碼
- (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];
});
}
此時(shí)只需要將試圖layer層放大就可以完成效果:
[capturePreviewsetAffineTransform:CGAffineTransformMakeScale(1.5,1.5)];
需注意代碼的順序顷啼。給layer層設(shè)置frame的代碼后放大昌屉。否則你會(huì)看到漆黑一片。
(后期插入補(bǔ)充):這段是測(cè)試人員發(fā)現(xiàn)的bug仪搔,由于上面將相機(jī)可視的layer層放大后導(dǎo)致超出控制器的view蜻牢。此時(shí)在處理完掃描事件結(jié)果會(huì)退出當(dāng)前掃描控制器抢呆。仔細(xì)看會(huì)發(fā)現(xiàn)控制器退出時(shí)卡在一半零點(diǎn)幾秒后再完全退出。(與之前的版本進(jìn)行對(duì)比)昌阿。此時(shí)修剪下capturePreview就行:
self.view.clipsToBounds=YES;
self.view.layer.masksToBounds=YES;
另一個(gè)問題:當(dāng)你變形放大展示的layer層后二維碼在可視界面之外也是可以進(jìn)行掃描獲取恳邀,于是乎我了解到將layer層的變大但是執(zhí)行任務(wù)還是以整個(gè)layer大小來掃描執(zhí)行谣沸。需要設(shè)置一個(gè)屬性setRectOfInterest,他是攝像中AVCaptureMetadataOutput類的一個(gè)屬性内地,他是通過一個(gè)CGRect來設(shè)置赋除,但是有兩點(diǎn):1、它是橫屏情況下的frame所以寬高和XY值需反向操作荆针。就是按照豎屏模式應(yīng)該將原先是XYWH要改為YXHW來設(shè)置。2秸妥、它是一個(gè)比例值以00開始為原點(diǎn)最大比例寬高為11(既全屏掃描情況下CGRect的寫法為(0沃粗,0最盅,1,1))涡贱。而且最大比例不是以手機(jī)尺寸比例问词,而是由capturePreview這個(gè)layer層為總比例。這也說明了為什么你能掃描超出屏幕尺寸外的二維碼信息內(nèi)容辰狡。
此處的scanCropRect接收了上面已設(shè)置好的中間掃描框的frame
CGFloat scanCropRectX = (capturePreview.frame.size.height - scanCropRect.size.height)/2;
CGFloat scanCropRectY = (capturePreview.frame.size.width - scanCropRect.size.width)/2;
//調(diào)整掃描位置
[captureOutputsetRectOfInterest:CGRectMake( scanCropRectX,scanCropRectY,scanCropRect.size.height/ capturePreview.frame.size.height ,scanCropRect.size.width/ capturePreview.frame.size.width )];
終于解決了掃描位置的問題