iOS7 系統二維碼掃描 (設置掃描區(qū)域、中空區(qū)域)

顯示出來掃描二維碼的界面,很簡單:

AVCaptureDevice? *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];

self.captureOutput = [[AVCaptureMetadataOutput alloc] init];

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

self.captureSession = [[AVCaptureSession alloc] init];

[_captureSession setSessionPreset:AVCaptureSessionPresetHigh];

if ([_captureSession canAddInput:captureInput]) {

[_captureSession addInput:captureInput];

}

if ([_captureSession canAddOutput:_captureOutput]) {

[_captureSession addOutput:_captureOutput];

}

_captureOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];

CGRect rect = CM(30, 100, Screen_Width - 60, 300);

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];

previewLayer.frame = self.view.bounds;

previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

[self.view.layer addSublayer:previewLayer];

[_captureSession startRunning];


按上述代碼設置之后,就可以掃描二維碼啦,但是這個是全屏掃描的,貌似無論你的previewLayer的frame設置的多大都是全屏掃描的。

而且一般設計時,有一個掃描區(qū)域之類的,怎么設置呢?

AVCaptureMetadataOutput 有一個屬性 rectOfInterest

rectOfInterest

就是設置元數據識別搜索的區(qū)域。

這個屬性有點問題,不是普通的CGRect,四個值都需要在0~1之間。

搜了好久看大家都是試的。最后看到rectOfInterest設置問題這個問題的回答后,才知道的。

AVCaptureVideoPreviewLayer 有個方法?

- (CGRect)metadataOutputRectOfInterestForRect:(CGRect)rectInLayerCoordinates

可以看看這個方法的說明:

方法說明

描述就是:把一個在previewlayer坐標系中的rect 轉換成 一個在metadataoutputs坐標系中的rect。

這個方法需要的rect參數是我們系統坐標系中的rect.

SO 。這就得到了我們需要的rectOfInterest。

驗證:

我們在 startRuning 之后(這里之前寫的是'之前',但是下面的代碼是在startRuning之后的)添加如下代碼:

[self.view.layer addSublayer:previewLayer];

[_captureSession startRunning];

CGRect intertRect = [previewLayer metadataOutputRectOfInterestForRect:rect];

CGRect layerRect = [previewLayer rectForMetadataOutputRectOfInterest:intertRect];

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

_captureOutput.rectOfInterest = intertRect;

運行設備是:iPhone6,(375, 667) ?設置的rect ?(想要的掃描區(qū)域) ?(30, 100, 315, 300)

打印結果:

intertRect ?{{0.14992503748125927, 0.080629685157421305}, {0.4497751124437781, 0.8387406296851575}}, ??

layerRect {{29.999999999999943, 99.999999999999972}, {315.00000000000006, 300}}

- (CGRect)rectForMetadataOutputRectOfInterest:(CGRect)rectInMetadataOutputCoordinates

方法說明

這個方法是把_captureOutput.rectOfInterest坐標系轉成preview layer 的坐標系的rect。

通過打印數據可以驗證成功,真機實驗也是正確的。

補充:設置中間透空區(qū)域

UIView *maskView = [[UIView alloc] initWithFrame:CM(0, 64, Screen_Width, Screen_Height - 64)];

maskView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];

[self.view addSubview:maskView];

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:CM(0, 0, Screen_Width, Screen_Height)];

[maskPath appendPath:[[UIBezierPath bezierPathWithRoundedRect:CM(30, 100 - 64, Screen_Width - 60, 300) cornerRadius:1] bezierPathByReversingPath]];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];

maskLayer.path = maskPath.CGPath;

maskView.layer.mask = maskLayer;



demo地址:github

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容