美文网首页
二维码扫描

二维码扫描

作者: xiari1991 | 来源:发表于2016-10-10 10:32 被阅读40次

    来源

    二维码扫描

    ios7之前我们实现二维码扫描一般是借助第三方来实现,但是在ios7之后系统自己提供二维码扫面的方法,而且用原生的方法性能要比第三方的要好很多

    @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于处理采集信息的代理
    {
        AVCaptureSession * session;//输入输出的中间桥梁
    }
    @end
    @implementation ViewController
     
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        //获取摄像设备
        AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        //创建输入流
        AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        if (!input) return;
        //创建输出流
        AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
        //设置代理 在主线程里刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        //设置有效扫描区域
        CGRect scanCrop=[self getScanCrop:_scanWindow.bounds readerViewBounds:self.view.frame];
         output.rectOfInterest = scanCrop;
        //初始化链接对象
        _session = [[AVCaptureSession alloc]init];
        //高质量采集率
        [_session setSessionPreset:AVCaptureSessionPresetHigh];
        
        [_session addInput:input];
        [_session addOutput:output];
        //设置扫码支持的编码格式(如下设置条形码和二维码兼容)
        output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
        
        AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
        layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
        layer.frame=self.view.layer.bounds;
        [self.view.layer insertSublayer:layer atIndex:0];
        //开始捕获
        [_session startRunning];
    }
    
    -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
        if (metadataObjects.count>0) {
            //[session stopRunning];
            AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
            //输出扫描字符串
            NSLog(@"%@",metadataObject.stringValue);
            //移除layer,停止扫描
        }
    }
    

    一些初始化的代码加上实现代理方法便完成了二维码扫描的工作,这里我们需要注意的是, 在二维码扫描的时候, 我们一般都会在屏幕中间放一个方框,用来显示二维码扫描的大小区间,这里我们在个AVCaptureMetadataOutput类中有一个rectOfInterest属性,它的作用就是设置扫描范围。

    这个CGRect参数和普通的Rect范围不太一样,它的四个值的范围都是0-1,表示比例。
    rectOfInterest都是按照横屏来计算的 所以当竖屏的情况下 x轴和y轴要交换一下。
    宽度和高度设置的情况也是类似。

    我们在上面设置有效扫描区域的方法如下

    #pragma mark-> 获取扫描区域的比例关系
    -(CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
    {
        
        CGFloat x,y,width,height;
        
        x = (CGRectGetHeight(readerViewBounds)-CGRectGetHeight(rect))/2/CGRectGetHeight(readerViewBounds);
        y = (CGRectGetWidth(readerViewBounds)-CGRectGetWidth(rect))/2/CGRectGetWidth(readerViewBounds);
        width = CGRectGetHeight(rect)/CGRectGetHeight(readerViewBounds);
        height = CGRectGetWidth(rect)/CGRectGetWidth(readerViewBounds);
        
        return CGRectMake(x, y, width, height);
        
    }
    

    相关文章

      网友评论

          本文标题:二维码扫描

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