iOS上实现二维码扫描

在iOS上实现二维码的扫描
使用AVFoundation框架
封装了一个类, demo在这里

  1. 实例化摄像头(捕获)设备
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

注意 : AVMediaTypeVideo应该是这个type, 和 AVMediaTypeAudio很像, 别弄错了, 找都找不到 - - 我这里就写错了, 找了半天才发现是这里错了.......

  1. 把摄像头设置为输入设备
    NSError *error = nil;
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
        if (error) {
            NSLog(@"There is no capture device. %@", error);
            // terminate the App, no camera!!!
            abort();
    }
  1. 设置输出
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    CGSize outputViewSize  = CGSizeMake(WIDTH - 100, WIDTH - 100);
    CGRect outputViewFrame = CGRectMake(WIDTH / 2 - outputViewSize.width / 2,
                                        HEIGHT / 2 - outputViewSize.height / 2,
                                        outputViewSize.width,
                                        outputViewSize.height);
    output.rectOfInterest = CGRectMake(outputViewFrame.origin.y / self.frame.size.height,
                                       outputViewFrame.origin.x / self.frame.size.width,
                                       outputViewFrame.size.height / self.frame.size.height,
                                       outputViewFrame.size.width / self.frame.size.width);
  1. 设置输出metadata delegate
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  1. 捕获
AVCaptureSession *session = [[AVCaptureSession alloc] init];
    session.sessionPreset = AVCaptureSessionPreset640x480;
    [session addInput:input];
    [session addOutput:output];
    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];

注意 : 必须在这里设置MetadataObjectTypes原因如下

Try adding both the input and output to the session before setting the metadata object types.
When you don't have the camera attached to the session yet, availableMetadataObjectTypes will be empty.

问题 : 即使是在这里设置, `availableMetadataObjectTypes`仍然为空, 导致设置失败...
原因 : 未知(待解决)
已解决 : 参看前文 注意
  1. 设置图像预览
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
    [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    [previewLayer setFrame:self.bounds];
  1. 添加到视图layer
[self.layer addSublayer:previewLayer];

写到这里, 已经能在view上看到摄像头的图像了....是不是很好玩~
而且, 系统也同时在对图像进行处理, 如果出现有二维码的话, 就会在下面的方法中处理:

#pragma mark AVCaptureMetadataOutputObjectsDelegate

//此方法是在识别到QRCode并且完成转换,如果QRCode的内容越大,转换需要的时间就越长。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    // code
    if (metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
        NSLog(@"QRCode: %@", obj.stringValue);
    } else {
        NSLog(@"faild");
    }
}

要想重写此方法, 需要签订AVCaptureMetadataOutputObjectsDelegate协议.
在这个方法里做任何事...

你可能感兴趣的:(iOS上实现二维码扫描)