美文网首页
扫描二维码

扫描二维码

作者: 简_爱SimpleLove | 来源:发表于2017-06-16 17:10 被阅读13次

    今天需要做到扫描二维码的功能,一开始想到了用三方,但是看到网上的文章说用原生的更好,所以就使用了苹果原生的进行识别,下面是简单的只是识别二维码,如果需要更复杂的操作可以看我推荐的文章

    - (void)sweepCode {
        // 1、获取摄像设备
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        // 2、创建输入流
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        
        // 3、创建输出流
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
        
        // 4、设置代理 在主线程里刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        // 5、初始化链接对象(会话对象)
        _session = [[AVCaptureSession alloc] init];
        //高质量采集率
        [_session setSessionPreset:AVCaptureSessionPresetHigh];
        
        // 5.1 添加会话输入
        NSError *error = nil;
        if (input) {
            //设置会话的输入设备
            [_session addInput:input];
        } else {
            NSLog(@"error - %@", [error localizedDescription]);
        }
        
        // 5.2 添加会话输出
    
        // 设置扫描范围(每一个取值0~1,以屏幕右上角为坐标原点)
        // 注:微信二维码的扫描范围是整个屏幕,这里并没有做处理(可不用设置)
    //    output.rectOfInterest = CGRectMake(0.05, 0.05, 0.9, 0.9);
        //CGRectMake(y, x, height, width);
        CGFloat width = SCREENWIDTH;// AVCaptureVideoPreviewLayer的对象的宽度
        CGFloat height = SCREENHEIGHT;// AVCaptureVideoPreviewLayer的对象的高度
        CGFloat extendSpace = 0.f;  //扩展宽出扫描框的长度
        output.rectOfInterest = CGRectMake((self.sweepCase.mr_y - extendSpace)/height, (self.sweepCase.mr_x - extendSpace)/width, (self.sweepCase.mr_height + 2 * extendSpace)/height, (self.sweepCase.mr_width + 2 * extendSpace)/width);
        [_session addOutput:output];
        
        // 6、设置输出数据类型,需要将元数据输出添加到会话后,才能指定元数据类型,否则会报错
        //设置扫描支持的编码格式(如下是设置条形码和二维码兼容)
        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
        
        // 7、实例化预览图层, 传递_session是为了告诉图层将来显示什么内容
        _layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
        _layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        //设置相机扫描框的大小
        _layer.frame = CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT);
        
        // 8、将图层插入当前视图
        [self.view.layer insertSublayer:_layer atIndex:0];
        // 9、启动会话 开始捕获
        [_session startRunning];
    }
    

    注意
    上面代码需要注意的是,设置扫描的范围。如果需要整个手机屏幕像玻璃一样,能看到手机对面,就不能设置AVCaptureVideoPreviewLayer为扫描框的大小,否则只有扫描框大小里面能透视。
    而设置AVCaptureVideoPreviewLayer的frame最好取当前屏幕的宽和高,不能取self.view.frame。不知道为什么,当我取self.view.frame的时候,长宽一直都是600,不准确。
    而想只有当二维码在扫描框内才识别的话,设置输出流的rectOfInterest属性,需要注意的是它的取值都是0~1,而且是以屏幕右上角为原点,顺序是CGRectMake(y, x, height, width)。

    最后需要在代理AVCaptureMetadataOutputObjectsDelegate方法中做需要做的操作

    #pragma mark - AVCaptureMetadataOutputObjectsDelegate
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
        NSString *zhQRCode = nil;
        for (AVMetadataObject *metadata in metadataObjects) {
            if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {  //判别是二维码类型
                zhQRCode = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
                break;
            }
        }
        NSLog(@"zhQRCode - %@", zhQRCode);
    }
    

    其他如果需要复杂一点的操作,可以看下面的文章

    参考文章
    iOS 二维码扫描(你想要的都在这里了)
    iOS原生二维码扫描
    iOS开发中用苹果原生API实现扫描二维码功能

    相关文章

      网友评论

          本文标题:扫描二维码

          本文链接:https://www.haomeiwen.com/subject/rdjmqxtx.html