之前做了一个功能,要求扫描二维码和微小型条码的扫描,微小型条码有多小,当客户一拿过来的时候我一脸蒙逼。条码高度就只有这一行字的高度,在纸上密密麻麻贴了一大条。这怎么扫?我马上用ZXing,ZBar什么的试了下,成功率极低。这显然无法满足需求。然后自己琢磨用系统提供的方法实现。先上代码:
/// 开始准备扫描(关键代码)
- (void)beginScanning {
//初始化相机设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input) {
return;
}
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//========核心代码==========设置扫描区域//
CGSize size = self.view.bounds.size;
CGRect cropRect = _scanWindow.frame;
CGFloat p1 = size.height/size.width;
CGFloat p2 = 1920./1080.;//使用 _session.sessionPreset = AVCaptureSessionPreset1920x1080;
if (p1 < p2) {
CGFloat fixHeight = self.view.bounds.size.width * 1920. / 1080.;
CGFloat fixPadding = (fixHeight - size.height)/2;
output.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;
output.rectOfInterest = CGRectMake(cropRect.origin.y/size.height,
(cropRect.origin.x + fixPadding)/fixWidth,
cropRect.size.height/size.height,
cropRect.size.width/fixWidth);
}
_session = [[AVCaptureSession alloc]init];
//扫描小型条码使用图片输出 1920x1080提高精确度
_session.sessionPreset = AVCaptureSessionPreset1920x1080;
[_session addInput:input];
[_session addOutput:output];
//设置条码类型
output.metadataObjectTypes=@[AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.frame = self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
[_session startRunning];}
前面没什么说的,初始化video,input,output。关键问题来了,正确设置扫描区域,这一步很重要。然后将sessionPreset设置为AVCaptureSessionPreset1920x1080,因为是要扫描微小型条形码,必须要提高图片输出质量,以此提高扫描成功率。一般的扫码使用AVCaptureSessionPreset640x480就够了。其次设置你要扫描的条码类型这里是AVMetadataObjectTypeCode128Code。