Chock Lee


  • 首页

  • 归档
Chock Lee

利用AVFoundation实现二维码扫描

发表于 2016-12-21 |

主要涉及的类:

1
2
3
4
5
6
7
8
9
AVCaptureDevice代表了物理捕获设备如:摄像机。用于配置等底层硬件设置相机的自动对焦模式。
AVCaptureDeviceInput是AVCaptureInput的子类,可以作为输入捕获会话,用AVCaptureDevice实例初始化。
AVCaptureSession管理输入(AVCaptureInput)和输出(AVCaptureOutput)流,包含开启和停止会话方法。
AVCaptureMetadataOutput是AVCaptureOutput的子类,处理输出捕获会话。捕获的对象传递给一个委托实线AVCaptureMetadataOutputObjectsDelegate协议。协议方法在指定的派发队列(dispatch queue)上执行。
AVCaptureVideoPreviewLayer是CALayer的一个子类,显示捕获到的相机输出流。

实现的基本流程如下:

1.首先获取流媒体信息我们需要用到AVCaptureSession对象来管理输入流和输出流;

2.然后利用AVCaptureVideoPreviewLayer对象来显示信息。

二维码扫描流程图.jpg

下面开始上代码了…

1.导入AVFoundation Framework的头文件,并添加AVCaptureSession和AVCaptureVideoPreviewLayer的属性

1
2
3
4
5
6
7
8
9
10
#import "QRCodeScanViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface QRCodeScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
// 闪关灯开启关闭标志
@property (nonatomic, assign) BOOL isLightOn;
@end

2.创建会话,读取输入流

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
// 开始扫描
- (BOOL)startScan {
    // 获取手机硬件设备
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    // 初始化输入流
    NSError *error = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    if (!input) {
        NSLog(@"%@",[error localizedDescription]);
        return NO;
    }
    // 创建会话
    _captureSession = [[AVCaptureSession alloc] init];
    // 添加输入流
    [_captureSession addInput:input];
    // 初始化输出流
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    // 添加输出流
    [_captureSession addOutput:output];
    // 创建dispatch queue
    dispatch_queue_t queue = dispatch_queue_create(kQRCodeScanQueueName, DISPATCH_QUEUE_CONCURRENT);
    //扫描的结果苹果是通过代理的方式区回调,所以outPut需要添加代理,并且因为扫描是耗时的工作,所以把它放到子线程里面
    [output setMetadataObjectsDelegate:self queue:queue];
    // 设置支持二维码和条形码扫描
    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
    // 创建输出对象
    _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
    [_previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    _previewLayer.frame = self.view.bounds;
    [self.view.layer insertSublayer:_previewLayer atIndex:0];
    // 开始会话
    [_captureSession startRunning];
    return YES;
}

3.结束扫描

1
2
3
4
5
6
// 结束扫描
- (void)stopScan {
    // 停止会话
    [_captureSession stopRunning];
    _captureSession = nil;
}

4.获取扫描结果并处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma mark -- AVCaptureMetadataOutputObjectsDelegate
// 扫描结果的代理回调方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if (metadataObjects != nil && metadataObjects.count > 0) {
        // 扫描到之后,停止扫描
        [self stopScan];
        // 获取结果并对其进行处理
        AVMetadataMachineReadableCodeObject *object = metadataObjects.firstObject;
        if ([[object type] isEqualToString:AVMetadataObjectTypeQRCode]) {
            NSString *result = object.stringValue;
            // 处理result
            NSLog(@"%@",result);
        } else {
            NSLog(@"不是二维码");
        }
    }
}

5.通常在扫描的时候会有开启闪光灯的功能,也是通过AVCaptureDevice来实现的。添加isLightOn属性,设置初始值为NO,并添加开关闪光灯的按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 开启和关闭闪光灯
- (IBAction)didClickedLightUpButton:(UIButton *)sender {
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    //判断手机是否有闪光灯
    if ([device hasTorch]) {
        //呼叫手机操作系统,控制手机硬件
        NSError *error = nil;
        [device lockForConfiguration:&error];
        if (self.isLightOn == NO) {
            [device setTorchMode:AVCaptureTorchModeOn];
            self.isLightOn = YES;
        } else {
            [device setTorchMode:AVCaptureTorchModeOff];
            self.isLightOn = NO;
        }
//结束对硬件的控制,跟上面的lockForConfiguration是配对的API
    [device unlockForConfiguration];
    }
}

最后附上github地址:https://github.com/chocklee/QRCodeScan

Chock Lee

Hexo 常用命令

发表于 2016-12-21 |

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

Chock Lee

Chock Lee

你可知道你的名字解释了我的一生

2 日志
GitHub Weibo
© 2016 Chock Lee
由 Hexo 强力驱动
主题 - NexT.Mist