iOS 开发AVFoundation系统原生二维码扫描实现

来源:互联网 发布:小猪cms源码2017 编辑:程序博客网 时间:2024/05/11 09:20
/*先在项目中导入AVFoundation.framework框架*/#import <UIKit/UIKit.h>#import <AVFoundation/AVFoundation.h>@interface QRViewController : UIViewController{    /**     *       AVCaptureSession:AVFoundation中的核心类,用于通过硬件获取、处理和输出视频。一个Capture Session由多个输入和多个输出组成,并控制输出帧的格式和分辨率。     AVCaptureVideoPreviewLayer:用于显示摄像头捕捉到得视频到UI。     */    AVCaptureSession *_captureSession;    AVCaptureVideoPreviewLayer *_previewLayer;}#import "QRViewController.h"#define Width self.view.frame.size.width#define Height self.view.frame.size.height@interface QRViewController ()<AVCaptureMetadataOutputObjectsDelegate>{    int num;    BOOL upOrdown;    NSTimer *timer;    //自定义界面    UIImageView *imageView;    UIButton *scanButton;    UILabel *labIntroudction;    UIImageView *line;}@end@implementation QRViewController- (void)viewDidLoad {    [super viewDidLoad];    _previewLayer.frame = self.view.frame;    [self initWith];    [self setupCaptureSession];    [self.view addSubview:scanButton];    [self.view addSubview:labIntroudction];    [self.view addSubview:imageView];    upOrdown = NO;    num =0;    timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation) userInfo:nil repeats:YES];}//自定义界面 - (void)initWith{    scanButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];    [scanButton setTitle:@"取消" forState:UIControlStateNormal];    scanButton.frame = CGRectMake(50, Height - 200, Width - 100, 50);    scanButton.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.5];    [scanButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];    labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake(50, 100, Width - 100, 50)];    labIntroudction.numberOfLines = 0;    labIntroudction.textColor=[UIColor whiteColor];    labIntroudction.text=@"将二维码图像置于矩形方框内,离手机摄像头10CM左右,系统会自动识别。";    labIntroudction.font = [UIFont systemFontOfSize:16.0];    labIntroudction.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pick_bg.png"]];    imageView.frame = CGRectMake(40, 170, Width - 80, Width - 80);    _line = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, imageView.frame.size.width - 20, 2)];    _line.image = [UIImage imageNamed:@"line.png"];    [imageView addSubview:_line];    self.view.backgroundColor = [UIColor clearColor];}-(void)animation{    if (upOrdown == NO) {        num ++;        _line.frame = CGRectMake(10, 10 + 2*num, imageView.frame.size.width - 20, 2);        if (2*num == CGRectGetHeight(imageView.frame) - 20) {            upOrdown = YES;        }    }    else {        num --;        _line.frame = CGRectMake(10, 10 + 2*num, imageView.frame.size.width - 20, 2);        if (num == 0) {            upOrdown = NO;        }    }}-(void)backAction{    [self dismissViewControllerAnimated:YES completion:^{        [timer invalidate];    }];}/** *   这个方法用于建立capture session。 如果session已经存在,则直接返回。 初始化video device,若设备没有摄像头,则直接返回。 初始化capture session。 通过video device创建video input。 查询session是否接受一个输入,如果接受,添加输入到session中。 最后,创建预览层并为其指定要预览的capture session。 */- (void)setupCaptureSession {    if (_captureSession) return;    /*    AVCaptureDevice:封装设备上的物理摄像头。对iPhone而言有前后两个摄像头。    AVCaptureDeviceInput:要添加一个AVCaptureDevice到session中,需要用AVCaptureDeviceInput来包裹一下。     */   // 首先我们应该判断当前设备是否有捕获数据流的设备。     AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];    if (!videoDevice) {        NSLog(@"No video camera on this device!");        return;    }     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];    //初始化一个 CaptureSession对象    _captureSession = [[AVCaptureSession alloc] init];    //设置会话的输入设备    if ([_captureSession canAddInput:input])    {        [_captureSession addInput:input];    }    //对应输出    AVCaptureMetadataOutput *captureMetadataOutput = [[ AVCaptureMetadataOutput alloc] init];    [_captureSession addOutput:captureMetadataOutput];    //设置扫描区域    [captureMetadataOutput setRectOfInterest:CGRectMake(imageView.frame.origin.y/ Height ,imageView.frame.origin.x/ Width , imageView.frame.size.width / Height, imageView.frame.size.height / Width)];    //创建一个队列    dispatch_queue_t metadataQueue = dispatch_queue_create("myQueue", 0);    [captureMetadataOutput setMetadataObjectsDelegate:self queue:metadataQueue];    [captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];    if([_captureSession canAddOutput:captureMetadataOutput])    {        [_captureSession addOutput:captureMetadataOutput];    }    // 降捕获的数据流展现出来    _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];    _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;    [_previewLayer setFrame:self.view.layer.bounds];    [self.view.layer addSublayer:_previewLayer];  //  开始捕获    [ _captureSession startRunning];}- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{  // 判断是否有数据,是否是二维码数据    if (metadataObjects != nil && [metadataObjects count] > 0) {        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];            //获得扫描的数据,并结束扫描            [self dismissViewControllerAnimated:YES completion:^{                [timer invalidate];                if(metadataObj.stringValue && [metadataObj.stringValue rangeOfString:@"http:"].location != NSNotFound)                {                    NSString *regex = @"http+:[^\\s]*";                    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];                    // 正则表达式判断 是否包含 http:                    if ([predicate evaluateWithObject:metadataObj.stringValue])                    {                        // 判断是不是我们自己的二维码                        if ([metadataObj.stringValue rangeOfString:@"http://m.pinlehuo.com/api.php"].location != NSNotFound) {                            NSLog(@"-------%@", metadataObj.stringValue);                        }else{                            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:metadataObj.stringValue]];                        }                    }                } else {                    NSLog(@"symbol.data = %@", metadataObj.stringValue);            }        }];       }}@end
0 0
原创粉丝点击