OC - 原生扫码(扫描二维码,条形码)

来源:互联网 发布:十送红军网络歌手 编辑:程序博客网 时间:2024/04/30 03:34
今天来总结一下,原生扫码。原生的比zbar量级要轻一些,在一些简单的扫码动作中,使用时很方便的。
原生扫码需添加<AVFoundation/AVFoundation.h>系统库,遵守AVCaptureMetadataOutputObjectsDelegate协议
下面直接上代码:


@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic,strong)AVCaptureSession *session;

@end


- (void)viewDidLoad {

    [superviewDidLoad];

    

    CGFloat kWidth = [UIScreenmainScreen].bounds.size.width;

    CGFloat kHeight = [UIScreenmainScreen].bounds.size.height;

    CGFloat QRcode_width = 150;

   

    NSString *mediaType =AVMediaTypeVideo;

    AVAuthorizationStatus authStatus = [AVCaptureDeviceauthorizationStatusForMediaType:mediaType];

    

    if(authStatus ==AVAuthorizationStatusRestricted ||

       authStatus == AVAuthorizationStatusDenied)

    {

        NSLog(@"相机权限受限");

        return;

    }

    else

    {

        // 获取摄像设备

        AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

        // 创建输入流

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

        // 创建输出流

        AVCaptureMetadataOutput *outPut = [[AVCaptureMetadataOutputalloc]init];

        /**

            设置范围 ( 若不需要限制区域扫描,rectOfInterest不需要设置 ,此demo限制扫描区域宽高为150的中心区域 )

           注意:坑爹地方!!    此处坐标不是传统意义上的坐标,而为比例关系的坐标,数值在[0,1]区间

                                坐标原点为右上角,x,y,width,height坐标互换,也就是说设置此处坐标时,应为( y , x , height , width)

         */

        outPut.rectOfInterest = CGRectMake(((kHeight - QRcode_width) / 2) / kHeight,

                                           ((kWidth - QRcode_width) / 2) / kWidth,

                                           QRcode_width / kHeight,

                                           QRcode_width / kWidth);

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

        [outPut setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

        

        // 初始化链接对象

        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];

    }

}


#pragma mark - AVCaptureMetadataOutputObjectsDelegate

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

{

    NSString *stringValue;

    if (metadataObjects.count >0)

    {

        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjectsobjectAtIndex:0];

        stringValue = metadataObject.stringValue;

        // 输出扫描字符串

        NSLog(@"metadataObject.stringValue = %@",metadataObject.stringValue);


/**

   根据 stringValue 设置你需要执行的事件

         */

    }

    // 停止捕获

    [self.sessionstopRunning];    

}


停止捕获后,界面会卡住。如果上述你执行的操作是跳到另一个界面,那么由下一个界面返回此界面时,界面依旧会卡住。若需要进入此界面就要扫码,则设置

- (void)viewWillAppear:(BOOL)animated

{

    [self.sessionstartRunning];

}


- (void)viewWillDisappear:(BOOL)animated

{

    [self.sessionstopRunning];

}

这样设置后,每次进入界面都会扫码。


0 0