iOS_使用AVCaptureSession实现二维码和条形码的
2016-06-07 本文已影响6046人
Mark_Ming
上一篇文章提到了如何生成一张清晰的二维码图片,今天我们来使用iOS7.0之后苹果官方提供给我们的用来扫描二维码和条形码的方法,可能听说过ZBar或者ZXing这两个相对古老的第三方,在没有官方API之前,这两个三方在32位时期给了我们莫大的帮助,深表感谢!但经过对系统自带方法的使用,我发现苹果官方写的API效率真的很高。下面我们来实现扫描:
第一步:
//导入AVFoundation框架
#import <AVFoundation/AVFoundation.h>
第二步:
//签协议,我们会在协议方法里获取到扫描结果
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
第三步:
@property(nonatomic, strong)AVCaptureSession *session;//输入输出的中间桥梁
第四步:
#pragma mark -- 开始扫描
- (void)startScanWithSize:(CGFloat)sizeValue
{
//获取摄像设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
//判断输入流是否可用
if (input) {
//创建输出流
AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
//设置代理,在主线程里刷新,注意此时self需要签AVCaptureMetadataOutputObjectsDelegate协议
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//初始化连接对象
self.session = [[AVCaptureSession alloc]init];
//高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
[_session addInput:input];
[_session addOutput:output];
//设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
//扫描区域大小的设置:(这部分也可以自定义,显示自己想要的布局)
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//设置为宽高为200的正方形区域相对于屏幕居中
layer.frame = CGRectMake((self.view.bounds.size.width - sizeValue) / 2.0, (self.view.bounds.size.height - sizeValue) / 2.0, sizeValue, sizeValue);
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获图像:
[_session startRunning];
}
}
第五步:
#pragma mark -- 调用扫描方法
- (void)viewDidLoad {
[super viewDidLoad];
//300为正方形扫描区域边长
[self startScanWithSize:300];
}
第六步:
#pragma mark - 扫面结果在这个代理方法里获取到
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
//获取到信息后停止扫描:
[_session stopRunning];
AVMetadataMachineReadableCodeObject *metaDataObject = [metadataObjects objectAtIndex:0];
//输出扫描字符串:
NSLog(@"%@", metaDataObject.stringValue);
//移除扫描视图:
AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)[[self.view.layer sublayers] objectAtIndex:0];
[layer removeFromSuperlayer];
}
}
注:有不足之处,还会继续研究完善,谢谢