标签:
二维码扫描的实现
#import "QRCodeViewController.h" #import <AVFoundation/AVFoundation.h> #import "Common.h" @interface QRCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate> @property (nonatomic, strong)AVCaptureDevice *device;//设备 @property (nonatomic, strong)AVCaptureInput *input;//输入端 @property (nonatomic, strong)AVCaptureMetadataOutput *output;//输出端 @property (nonatomic, strong)AVCaptureSession *session;//会话 @property (weak, nonatomic) IBOutlet UIView *preView;//显示预览layer @property (nonatomic, weak)UIImageView *animationView; @property (nonatomic, strong)NSTimer *animationTimer; @end @implementation QRCodeViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. //配置UI效果 //添加扫描的边框 UIImage *image = [UIImage imageNamed:@"qrcode_border"]; UIImage *boundImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(25, 25, 26, 26)]; UIImageView *imageView = [[UIImageView alloc] initWithImage:boundImage]; //左边从70px开始 CGFloat width = kScreenWidth - 70 *2; [imageView setFrame:CGRectMake(70, 170, width, width)]; [self.view addSubview:imageView]; // 添加上动画的图片 UIImageView *animationView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -width, width, width)]; [animationView setImage:[UIImage imageNamed:@"qrcode_scanline_qrcode"]]; //添加到方块视图上 [imageView addSubview:animationView]; //超出父视图区域不显示 imageView.clipsToBounds = YES; self.animationView = animationView; self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:.02f target:self selector:@selector(changeImage:) userInfo:nil repeats:YES]; UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancel)]; self.navigationItem.leftBarButtonItem = leftButton; } -(void)cancel{ [self stopRead]; [self.navigationController popViewControllerAnimated:YES]; } -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; //开始二维码扫描 [self reading]; } -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; //停止二维码扫描 [self stopRead]; } -(void)changeImage:(NSTimer *)timer{ //更新图片产生动画 self.animationView.frame = CGRectOffset(self.animationView.frame, 0, 2); if (self.animationView.frame.origin.y >= self.animationView.superview.frame.size.height) { self.animationView.frame = CGRectMake(0, -CGRectGetHeight(self.animationView.superview.frame), self.animationView.frame.size.width, self.animationView.frame.size.height); } } //二维码扫描 -(void)reading{ //1.构造device 获得扫描设备:(摄像头) self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //2.构造input 生成连接设备和session的input NSError *error; self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error]; //3.构造output,元数据 self.output = [[AVCaptureMetadataOutput alloc] init]; //4.session self.session = [[AVCaptureSession alloc] init]; [self.session addInput:self.input]; [self.session addOutput:self.output];
//5.配置output //设置delegate,输出的类型 一定要将output添加到session中后,再设置 dispatch_queue_t queue = dispatch_queue_create("queue", NULL); [self.output setMetadataObjectsDelegate:self queue:queue]; [self.output setMetadataObjectTypes:self.output.availableMetadataObjectTypes]; //6.添加预览功能 可以预览device捕捉到的画面 AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; [layer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; [layer setFrame:self.view.bounds]; [self.preView.layer addSublayer:layer]; //生成一个图片,周围半透明,中间不透明,作为layer的mask层 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [[UIScreen mainScreen] scale]); CGContextRef context = UIGraphicsGetCurrentContext(); //绘制底层的半透明效果 CGContextSetRGBFillColor(context, 0, 0, 0, 0.9f); CGContextAddRect(context, self.view.bounds); CGContextFillPath(context); //绘制中间的不透明区域 CGContextSetRGBFillColor(context, 1, 1, 1, 1.f); //中间方块区域 CGContextAddRect(context, self.animationView.superview.frame); CGContextFillPath(context); //生成图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //释放资源 UIGraphicsEndImageContext(); CALayer *maskLayer= [[CALayer alloc] init]; maskLayer.bounds = self.preView.bounds; maskLayer.position = self.preView.center; maskLayer.contents = (__bridge id)(image.CGImage); layer.mask = maskLayer; layer.masksToBounds = YES; //7.启动服务 [self.session startRunning]; [self.animationTimer fire]; } //停止二维码扫描 -(void)stopRead{ [self.session stopRunning]; //停止一个timer [self.animationTimer invalidate]; }
//代理服务,注意该方法的调用是在穿行队列中 -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ //接收元数据 if (metadataObjects.count != 0) { AVMetadataMachineReadableCodeObject *codeObj = metadataObjects[0]; if ([codeObj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) { NSLog(@"%@", [codeObj stringValue]); //在主线程中刷新UI [self performSelectorOnMainThread:@selector(cancel) withObject:nil waitUntilDone:YES]; } } }
标签:
原文地址:http://www.cnblogs.com/10-19-92/p/4955776.html