使用苹果原生API进行二维码和条形码的扫描

来源:互联网 发布:减速箱装配图 淘宝 编辑:程序博客网 时间:2024/05/29 16:31

最近需要用到二维码的扫描,发现苹果有自己的原生的api,这里简单介绍一下.

首先需要引入AVFoundation.framework 库

在相应的viewController里边引入头文件.

#import <AVFoundation/AVFoundation.h>

//遵守代理

@interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic,strong)AVCaptureSession *captureSession;//输入输出的中间桥梁

@end


接下来就是进行二维码的扫描

#pragma mark - 开始扫描

/**

 *  开始扫描

 */

- (void)beginScanning

{

    //获取摄像设备

    AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    //创建输入流

    AVCaptureDeviceInput * input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:nil];

    if (!input) 

    return;

    //创建输出流

    AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutputalloc]init];

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

    [output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

    //设置有效扫描区域

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

    //初始化链接对象

    self.session = [[AVCaptureSessionalloc]init];

    //高质量采集率

    [self.sessionsetSessionPreset:AVCaptureSessionPresetHigh];

    

    [self.sessionaddInput:input];

    [self.sessionaddOutput:output];

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

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

    

    AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayerlayerWithSession:self.session];

    layer.videoGravity =AVLayerVideoGravityResizeAspectFill;

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

    [self.view.layerinsertSublayer:layeratIndex:0];

    //开始捕获

    [self.sessionstartRunning];

}


/**

 *  扫描的输出结果

 *

 *  @param metadataObjects 扫描到的数据

 */

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

{

    if (metadataObjects.count >0) {

        [self.sessionstopRunning];

        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjectsobjectAtIndex:0];

        

        UIAlertView *alert = [[UIAlertViewalloc]initWithTitle:@"扫描结果"message:metadataObject.stringValuedelegate:selfcancelButtonTitle:@"退出"otherButtonTitles:@"再次扫描",nil];

        [alert show];

    }

}


- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

    if (buttonIndex == 0) {

        [self.navigationControllerpopViewControllerAnimated:YES];

    } else if (buttonIndex ==1) {

        [self.sessionstartRunning];

    }

}

AVCaptureMetadataOutput类中有一个这样的属性(在IOS7.0之后可用):

@property(nonatomicCGRect rectOfInterest;

这个属性大致意思就是告诉系统它需要注意的区域,大部分APP的扫码UI中都会有一个框,提醒你将条形码放入那个区域,这个属性的作用就在这里,它可以设置一个范围,只处理在这个范围内捕获到的图像的信息。在使用这个属性的时候。需要几点注意:

1、这个CGRect参数和普通的Rect范围不太一样,它的四个值的范围都是0-1,表示比例。

2、经过测试发现,这个参数里面的x对应的恰恰是距离左上角的垂直距离,y对应的是距离左上角的水平距离。

3、宽度和高度设置的情况也是类似。

3、举个例子如果我们想让扫描的处理区域是屏幕的下半部分,我们这样设置

?
1
output.rectOfInterest=CGRectMake(0.5,0,0.5, 1);


另一个就是扫描相册里边的图片二维码
当点击从相册选取时掉用以下方法

if([UIImagePickerControllerisSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {

        // 1.初始化相册拾取器

        UIImagePickerController *controller = [[UIImagePickerControlleralloc] init];

        // 2.设置代理

        controller.delegate = self;

        // 3.设置资源:

        controller.sourceType =UIImagePickerControllerSourceTypeSavedPhotosAlbum;

        controller.modalTransitionStyle =UIModalTransitionStyleCoverVertical;

        [selfpresentViewController:controller animated:YEScompletion:NULL];

        

    } else {

        UIAlertView * alert = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"设备不支持访问相册,请在设置->隐私->照片中进行设置!"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];

        [alert show];

    }


/**

 *  从相册选取图片监听

 */

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

{

    //1.获取选择的图片

    UIImage *image = info[UIImagePickerControllerOriginalImage];

    //2.初始化一个监测器

    CIDetector *detector = [CIDetectordetectorOfType:CIDetectorTypeQRCodecontext:niloptions:@{CIDetectorAccuracy : CIDetectorAccuracyHigh}];

    

    [picker dismissViewControllerAnimated:YEScompletion:^{

        //监测到的结果数组

        NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];

        if (features.count >0) {

            /**结果对象 */

            CIQRCodeFeature *feature = [featuresobjectAtIndex:0];

            NSString *scannedResult = feature.messageString;

            UIAlertView * alertView = [[UIAlertViewalloc]initWithTitle:@"扫描结果"message:scannedResult delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];

            [alertView show];

            

        }

        else{

            UIAlertView * alertView = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"该图片没有包含一个二维码!"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil,nil];

            [alertView show];

        }

    }];

}




0 0
原创粉丝点击