iOS6.0以后,二維碼識別便拋棄了ZBar和ZXing,而是使用掃描靈敏度和性能都最優的AVFoundation框架。如果需要兼容iOS7.0以下版本,可以使用ZBar和ZXing,但是在這里就不再對它們多做贅述了。直奔主題,說一說怎么通過對AVFoundation的優化,進一步提高二維碼識別的靈敏度和速度。
1.設置 sessionPreset 屬性
測試的時候,有些二維碼非常小,有的時候距離二維碼比較遠,都會造成無法正常識別二維碼。距離遠的還可以將手機湊近點,以提高掃描的靈敏度。但是二維碼本身就小的,湊近了無法聚焦,離遠了又無法識別,必然需要通過相機的像素進行優化。
AVCaptureSession 可以設置 sessionPreset 屬性,這個決定了視頻輸入每一幀圖像質量的大小。
- AVCaptureSessionPreset320x240
- AVCaptureSessionPreset352x288
- AVCaptureSessionPreset640x480
- AVCaptureSessionPreset960x540
- AVCaptureSessionPreset1280x720
- AVCaptureSessionPreset1920x1080
以上列舉了部分的屬性值,分別代表輸入圖片質量大小,一般來說AVCaptureSessionPreset640x480就夠使用,但是如果要保證較小的二維碼圖片能快速掃描,最好設置高些,如AVCaptureSessionPreset1920x1080(就是我們常說的1080p)。
- AVCaptureSessionPreset3840x2160
另外還有一個屬性值,是iOS9.0以后的,適合3840x2160(UHD 4K)視頻輸出,建議慎用,用不好的話,程序會崩。
2.設置rectOfInterest屬性
AVCaptureMetadataOutput可以設置rectOfInterest屬性,這個屬性是用來限制二維碼掃描范圍的,一般設定的范圍都是我們給定好的正方形大小。
_output.rectOfInterest =[self rectOfInterestByScanViewRect:imageView.frame];
或者:
_output.rectOfInterest =[self rectOfInterestByScanViewRect:CGRectMake(0.1, 0, 0.9, 1)];
現在對rectOfInterest屬性的大小,進行了一些修正。代碼如下:
CGSize size = self.view.bounds.size;
CGRect cropRect = CGRectMake(40, 100, 240, 240);
CGFloat p1 = size.height/size.width;
CGFloat p2 = 1920./1080.; //使用了1080p的圖像輸出
if (p1 < p2) {
CGFloat fixHeight = self.view.bounds.size.width * 1920. / 1080.;
CGFloat fixPadding = (fixHeight - size.height)/2;
captureOutput.rectOfInterest = CGRectMake((cropRect.origin.y + fixPadding)/fixHeight,
cropRect.origin.x/size.width,
cropRect.size.height/fixHeight,
cropRect.size.width/size.width);
} else {
CGFloat fixWidth = self.view.bounds.size.height * 1080. / 1920.;
CGFloat fixPadding = (fixWidth - size.width)/2;
captureOutput.rectOfInterest = CGRectMake(cropRect.origin.y/size.height,
(cropRect.origin.x + fixPadding)/fixWidth,
cropRect.size.height/size.height,
cropRect.size.width/fixWidth);
}
這樣以來,確實大大提高了掃描的靈敏度,哪怕是二維碼距離稍遠也能夠輕松掃描出結果。親測有效,歡迎嘗試。