示例源码地址:https://github.com/chaseDeil/YQOriginQRDemo
因项目需求,很多都会涉及到二维码扫描及生成功能,以前用过两个第三方库ZBar和ZXing,但在集成过程中,很多人可能都会遇到或多或少的问题,解决起来头痛不已。而在iOS7开始官方集成了二维码扫描和生成功能,使用起来更加便捷、高效,本偏文章主要介绍其用法。
一、二维码扫描
要使用源生二维码扫描功能,首先要在工程中添加AVFoundation.framework框架到build phase的”Link Binary With Libraries”之下。接下来就是代码的事情了,先导入框架
#import <AVFoundation/AVFoundation.h>
然后实现AVCaptureMetadataOutputObjectsDelegate协议
@interface YQQRViewController ()<AVCaptureMetadataOutputObjectsDelegate>
接下来代码实现:
- (void)createQR
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!_device) {
//初始化捕捉设备
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//用_device创建输入流
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
//创建媒体数据输出流
_output = [[AVCaptureMetadataOutput alloc] init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//实例化捕捉会话
_session = [[AVCaptureSession alloc] init];
[_session setSessionPreset:AVCaptureSessionPresetHigh];
if ([_session canAddInput:self.input]) {
//将输入流添加到会话
[_session addInput:self.input];
_canOpen = YES;
} else {
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"打开相机权限" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"去设置", nil];
[alert show];
});
}
if (_canOpen) {
if ([_session canAddOutput:self.output]) {
//将媒体输出流添加到会话中
[_session addOutput:self.output];
}
// 条形码/二维码
_output.metadataObjectTypes =[NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil];
// 只支持二维码
// _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
//实例化预览图层
_preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
//设置预览图层填充方式
_preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
// 控制扫描区域 参考:http://blog.youkuaiyun.com/lc_obj/article/details/41549469
[_output setRectOfInterest:CGRectMake(Top_Height / kScreenHeight, ((kScreenWidth - MiddleWidth) / 2) / kScreenWidth, MiddleWidth / kScreenHeight, MiddleWidth / kScreenWidth)];
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程
_preview.frame =CGRectMake(0,0,kScreenWidth,kScreenHeight);
[self.view.layer insertSublayer:self.preview atIndex:0];
});
if (_canOpen) {
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程
timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(YQAnimation) userInfo:nil repeats:YES];
[_session startRunning];
});
}
}
}
});
}
实现协议方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if ([metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *matadataObject = [metadataObjects objectAtIndex:0];
NSLog(@"%@", matadataObject.stringValue);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"扫描信息" message:matadataObject.stringValue delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
[alert show];
[_session stopRunning];
[timer invalidate];
timer = nil;
}
}
二、二维码生成
主要实现
- (void)createQRCode
{
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [@"有限责任公司 注册号:210403)。http://gext.lngs.gov.cn" dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
CIImage *outputImg = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef imgRef = [context createCGImage:outputImg fromRect:[outputImg extent]];
UIImage *img = [UIImage imageWithCGImage:imgRef];
_imgView.image = img;
//在ImageView的Layer上使用下面代码添加阴影
// _imgView.layer.shadowOffset=CGSizeMake(0, 0.5);//设置阴影的偏移量
// _imgView.layer.shadowRadius=1;//设置阴影的半径
// _imgView.layer.shadowColor=[UIColor blackColor].CGColor;//设置阴影的颜色为黑色
// _imgView.layer.shadowOpacity=0.3;
}
以上代码仅为部分实现,具体请查看Demo,代码写的比较粗糙,大神轻喷,如果觉得还能用,请给个star~
示例源码地址:https://github.com/chaseDeil/YQOriginQRDemo
扫描区域控制:http://blog.youkuaiyun.com/lc_obj/article/details/41549469