使用 AVFoundation类 可以使相机识别二维码和条形码
Demo地址:
https://github.com/muyan091115/Scan
效果图:
Demo.gif一、info.plist插入申请权限提示:
info.plist.png或者以代码方式打开 加入
<key>NSCameraUsageDescription</key>
<string>需要扫描</string>
二、请求相机权限
mediaType 选择 AVMediaTypeVideo 只需要录像的权限
#import <AVFoundation/AVFoundation.h>
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
dispatch_async(dispatch_get_main_queue(), ^{
if (granted) {
[self setupScan];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"没有权限" message:@"" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil];
[alertView show];
}
});
}];
三、设置相机属性 并 开始扫描
- 获取相机设备
- 创建输入输出流
- 设置代理 并 指定刷新的线程
- 创建session 设置其采集率 并为session添加输入输出流
- 设置输出流支持的格式
a、 二维码:AVMetadataObjectTypeQRCode
b、 条形码:
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code - 根据session 创建相机layer
- 把相机layer添加到vc试图中
⚠️ 注意:尽量不要把二维码和条形码的格式都支持到输出流,这样会影响扫描的性能。
- (void)setupScan {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
self.session = [[AVCaptureSession alloc]init];
[self.session setSessionPreset:AVCaptureSessionPresetHigh];
[self.session addInput:input];
[self.session addOutput:output];
//qrcode
if ([self.type isEqualToString:@"01"]) {
output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode];
//barcode
} else if ([self.type isEqualToString:@"02"]) {
output.metadataObjectTypes=@[AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code];
}
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.frame = self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:10003];
[self.session startRunning];
}
四、在代理方法中获取扫码结果
返回的类型是AVMetadataMachineReadableCodeObject的数组
获取第一个的stringValue属性,就是对应扫码的内容
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0];
NSString *result = metadataObject.stringValue;
self.hasScan(result);
[self.session stopRunning];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
获取结果后block 回传给上一级vc
网友评论