今天需要做到扫描二维码的功能,一开始想到了用三方,但是看到网上的文章说用原生的更好,所以就使用了苹果原生的进行识别,下面是简单的只是识别二维码,如果需要更复杂的操作可以看我推荐的文章
- (void)sweepCode {
// 1、获取摄像设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 2、创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
// 3、创建输出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
// 4、设置代理 在主线程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 5、初始化链接对象(会话对象)
_session = [[AVCaptureSession alloc] init];
//高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
// 5.1 添加会话输入
NSError *error = nil;
if (input) {
//设置会话的输入设备
[_session addInput:input];
} else {
NSLog(@"error - %@", [error localizedDescription]);
}
// 5.2 添加会话输出
// 设置扫描范围(每一个取值0~1,以屏幕右上角为坐标原点)
// 注:微信二维码的扫描范围是整个屏幕,这里并没有做处理(可不用设置)
// output.rectOfInterest = CGRectMake(0.05, 0.05, 0.9, 0.9);
//CGRectMake(y, x, height, width);
CGFloat width = SCREENWIDTH;// AVCaptureVideoPreviewLayer的对象的宽度
CGFloat height = SCREENHEIGHT;// AVCaptureVideoPreviewLayer的对象的高度
CGFloat extendSpace = 0.f; //扩展宽出扫描框的长度
output.rectOfInterest = CGRectMake((self.sweepCase.mr_y - extendSpace)/height, (self.sweepCase.mr_x - extendSpace)/width, (self.sweepCase.mr_height + 2 * extendSpace)/height, (self.sweepCase.mr_width + 2 * extendSpace)/width);
[_session addOutput:output];
// 6、设置输出数据类型,需要将元数据输出添加到会话后,才能指定元数据类型,否则会报错
//设置扫描支持的编码格式(如下是设置条形码和二维码兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
// 7、实例化预览图层, 传递_session是为了告诉图层将来显示什么内容
_layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//设置相机扫描框的大小
_layer.frame = CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT);
// 8、将图层插入当前视图
[self.view.layer insertSublayer:_layer atIndex:0];
// 9、启动会话 开始捕获
[_session startRunning];
}
注意
上面代码需要注意的是,设置扫描的范围。如果需要整个手机屏幕像玻璃一样,能看到手机对面,就不能设置AVCaptureVideoPreviewLayer为扫描框的大小,否则只有扫描框大小里面能透视。
而设置AVCaptureVideoPreviewLayer的frame最好取当前屏幕的宽和高,不能取self.view.frame。不知道为什么,当我取self.view.frame的时候,长宽一直都是600,不准确。
而想只有当二维码在扫描框内才识别的话,设置输出流的rectOfInterest属性,需要注意的是它的取值都是0~1,而且是以屏幕右上角为原点,顺序是CGRectMake(y, x, height, width)。
最后需要在代理AVCaptureMetadataOutputObjectsDelegate方法中做需要做的操作
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
NSString *zhQRCode = nil;
for (AVMetadataObject *metadata in metadataObjects) {
if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) { //判别是二维码类型
zhQRCode = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
break;
}
}
NSLog(@"zhQRCode - %@", zhQRCode);
}
其他如果需要复杂一点的操作,可以看下面的文章
参考文章
iOS 二维码扫描(你想要的都在这里了)
iOS原生二维码扫描
iOS开发中用苹果原生API实现扫描二维码功能
网友评论