iOS使用AVFoundation实现二维码扫描

Posted 罗小浮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS使用AVFoundation实现二维码扫描相关的知识,希望对你有一定的参考价值。

实现过程如下:

Step1:需要导入:AVFoundation Framework 包含头文件:

#import <AVFoundation/AVFoundation.h>

Step2:设置捕获会话

设置 AVCaptureSession 和 AVCaptureVideoPreviewLayer 成员

1
2
3
4
5
6
7
8
9
10
    #import <AVFoundation/AVFoundation.h>

    static const char *kScanQRCodeQueueName = "ScanQRCodeQueue";

    @interface ViewController () <AVCaptureMetadataOutputObjectsDelegate>
    .....
    @property (nonatomic) AVCaptureSession *captureSession;
    @property (nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
    @property (nonatomic) BOOL lastResult;
    @end

Step3:创建会话,读取输入流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    - (BOOL)startReading
    {
        // 获取 AVCaptureDevice 实例
        NSError * error;
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        // 初始化输入流
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
        if (!input) {
            NSLog(@"%@", [error localizedDescription]);
            return NO;
        }
        // 创建会话
        _captureSession = [[AVCaptureSession alloc] init];
        // 添加输入流
        [_captureSession addInput:input];
        // 初始化输出流
        AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
        // 添加输出流
        [_captureSession addOutput:captureMetadataOutput];

        // 创建dispatch queue.
        dispatch_queue_t dispatchQueue;
        dispatchQueue = dispatch_queue_create(kScanQRCodeQueueName, NULL);
        [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
        // 设置元数据类型 AVMetadataObjectTypeQRCode
        [captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];

        // 创建输出对象
        _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
        [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
        [_videoPreviewLayer setFrame:_sanFrameView.layer.bounds];
        [_sanFrameView.layer addSublayer:_videoPreviewLayer];
        // 开始会话
        [_captureSession startRunning];

        return YES;
    }

Step4:停止读取

1
2
3
4
5
6
7
    - (void)stopReading
    {
        // 停止会话
        [_captureSession stopRunning];
        _captureSession = nil;
    }

Step5:获取捕获数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
  fromConnection:(AVCaptureConnection *)connection
{
    if (metadataObjects != nil && [metadataObjects count] > 0) {
        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
        NSString *result;
        if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
            result = metadataObj.stringValue;
        } else {
            NSLog(@"不是二维码");
        }
        [self performSelectorOnMainThread:@selector(reportScanResult:) withObject:result waitUntilDone:NO];
    }
}

Step6:处理结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  - (void)reportScanResult:(NSString *)result
  {
      [self stopReading];
      if (!_lastResult) {
          return;
      }
      _lastResut = NO;
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"二维码扫描"
                                                      message:result
                                                     delegate:nil
                                            cancelButtonTitle:@"取消"
                                            otherButtonTitles: nil];
      [alert show];
      // 以下处理了结果,继续下次扫描
      _lastResult = YES;
  }

以上基本就是二维码的获取流程

以上是关于iOS使用AVFoundation实现二维码扫描的主要内容,如果未能解决你的问题,请参考以下文章

Swift:使用系统AVFoundation实现二维码扫描和生成

iOS开发--二维码的扫描

Swift AVFoundation 二维码扫描和生成

iOS二维码扫描

IOS 二维码扫描

IOS二维码扫描IOS7系统实现