原生二维码的识别

iOS原生实现二维码识别
本文介绍了如何在iOS应用中使用AVFoundation框架进行二维码识别,包括初始化扫描视图、设置权限、处理扫描结果以及从相册选取图片识别二维码的实现步骤。

代码

@interface POIPersonalCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于处理采集信息的代理

@property (strong,nonatomic)AVCaptureDevice * device;

@property (strong,nonatomic)AVCaptureDeviceInput * input;

@property (strong,nonatomic)AVCaptureMetadataOutput * output;

@property (strong,nonatomic)AVCaptureSession * session;

@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;

@property (strong, nonatomic) UIImageView *scanView;

@property (strong, nonatomic) UIImageView *boxView;

@end


@implementation POIPersonalCodeViewController

- (void)viewDidLoad {

    [super viewDidLoad];

//设置右边按钮,请自定义

    [self setUpRightBtn];

    [self createUI];

}


- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    [_session startRunning];

}


- (void)setUpRightBtn {

    __block POIPersonalCodeViewController *weakself = self;

    [self setCustomRightButtonImage:[UIImage imageNamed:@"picture"] clickCallBack:^{

//调用从相册识别二维码图片方法

        [weakself sendPhotoFromAlbum];

    }];

}


- (void)sendPhotoFromAlbum{

    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc]init];

    imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;

    imagePickerController.allowsEditing = YES;

    imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    UIImage *blackImage = [UIImage poi_imageWithColor:POIHexColor(0x302f3ff2)];

    [imagePickerController.navigationBar setBackgroundImage:blackImage forBarMetrics:UIBarMetricsDefault];

    imagePickerController.delegate = self;

    self.imagePickerController = imagePickerController;

    [self presentViewController:imagePickerController animated:true completion:nil];

}


-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

[picker dismissViewControllerAnimated:YES completion:nil];

    UIImage *editedImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode

                                              context:[[CIContext alloc] init]

                                              options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}];

    CIImage *img = [CIImage imageWithCGImage:editedImage.CGImage];

    NSArray *features = [detector featuresInImage:img];

    if (features.count >=1) {

        CIQRCodeFeature *feature = [features objectAtIndex:0];

        NSLog(@"%@",feature.messageString);

        [self typeJump:feature.messageString];

    } else {

        [MBProgressHUD showMessage:@"无可识别的二维码" afterDelay:2.0f];

    }

}


//创建视图

- (void)createUI {

    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

    if (status == AVAuthorizationStatusRestricted || status ==AVAuthorizationStatusDenied){

        [MBProgressHUD showMessage:@"请设置允许我来访问您的相机" afterDelay:2.0];

    } else {

    //获取摄像设备

    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    //创建输入流

    _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];

    //创建输出流

    _output = [[AVCaptureMetadataOutput alloc]init];

    //设置代理 在主线程里刷新

    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

    //output.rectOfInterest = CGRectMake(0.5, 0, 0.5, 0.5);

    [_output setRectOfInterest:CGRectMake((120)/ScreenSizeHeight,0.2,300/ScreenSizeHeight,250/ScreenSizeWidth)];

    //初始化链接对象

    _session = [[AVCaptureSession alloc]init];

    //高质量采集率

    [_session setSessionPreset:AVCaptureSessionPreset1920x1080];

    if ([_session canAddInput:self.input]) {

        [_session addInput:self.input];

    }

    if ([_session canAddOutput:self.output]) {

        [_session addOutput:self.output];

    }

    //设置扫码支持的编码格式(如下设置条形码和二维码兼容)

    _output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];

    // Preview

    _preview =[AVCaptureVideoPreviewLayer layerWithSession:_session];

    _preview.videoGravity =AVLayerVideoGravityResizeAspectFill;

    _preview.frame = self.view.layer.bounds;

    [self.view.layer insertSublayer:_preview atIndex:0];

    }

    //扫描框

    _boxView = [[UIImageView alloc] initWithFrame:CGRectMake((ScreenSizeWidth-220)/2,124,220,220)];

    _boxView.image = [UIImage imageNamed:@"scan_bg.png"];

    [self.view addSubview:_boxView];

    //创建模糊效果

    [self setOverView];

    //描述文字

    UILabel *labIntroudction= [[UILabel alloc] initWithFrame:CGRectMake((ScreenSizeWidth-220)/2, _boxView.bottom+10, 220,50)];

    labIntroudction.backgroundColor = [UIColor clearColor];

    labIntroudction.numberOfLines=2;

    labIntroudction.textColor=[UIColor colorWithRed:1.00 green:1.00 blue:1.00 alpha:0.8];

    labIntroudction.text=@"将二维码放入框内,即可自动扫描";

    labIntroudction.font = [UIFont systemFontOfSize:15];

    [self.view addSubview:labIntroudction];

    [_session startRunning];

    [self loopDrawLine];

}


//添加模糊效果

- (void)setOverView {

    CGFloat width = CGRectGetWidth(self.view.frame);

    CGFloat height = CGRectGetHeight(self.view.frame);

    CGFloat x = CGRectGetMinX(_boxView.frame);

    CGFloat y = CGRectGetMinY(_boxView.frame);

    CGFloat w = CGRectGetWidth(_boxView.frame);

    CGFloat h = CGRectGetHeight(_boxView.frame);

    [self creatView:CGRectMake(0, 0, width, y)];

    [self creatView:CGRectMake(0, y, x, h)];

    [self creatView:CGRectMake(0, y + h, width, height - y - h)];

    [self creatView:CGRectMake(x + w, y, width - x - w, h)];

}


- (void)creatView:(CGRect)rect {

    UIView *view = [[UIView alloc] initWithFrame:rect];

    view.backgroundColor = [UIColor blackColor];

    view.alpha = 0.5;

    [self.view addSubview:view];

}

//扫描线

- (void)loopDrawLine {

    //扫描线

    UIImage *lineImage = [UIImage imageNamed:@"scan_line.png"];

    CGFloat x = CGRectGetMinX(_boxView.frame);

    CGFloat y = CGRectGetMinY(_boxView.frame);

    CGFloat w = CGRectGetWidth(_boxView.frame);

    CGFloat h = CGRectGetHeight(_boxView.frame);

    CGRect start = CGRectMake(x, y, w, 2);

    CGRect end = CGRectMake(x, y + h - 2, w, 2);

    if (!_scanView) {

        _scanView = [[UIImageView alloc] initWithImage:lineImage];

        _scanView.frame = start;

        [self.view addSubview:_scanView];

    } else {

        _scanView.frame = start;

    }

    __weak typeof(self) SHB = self;

    [UIView animateWithDuration:2 animations:^{

        _scanView.frame = end;

    } completion:^(BOOL finished) {

        [SHB loopDrawLine];

    }];

}

//扫描结果

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{

    //判断是否有数据

    if (metadataObjects != nil && [metadataObjects count] > 0) {

        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];

        //判断回传的数据类型

        if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {

            [_session stopRunning];

            NSLog(@"%@",metadataObj.stringValue);

        }

    }

}


- (void)viewDidDisappear:(BOOL)animated {

    [_session stopRunning];


}

- (void)dealloc {

    _session = nil;

}

@end


注意:从相册识别二维码 经过测试 只能基于iphone6 或以上  不然是 CIDetector为nil 有解决该问题的大神还望回复评论,指点一二。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值