关于二维码扫描有不少优秀第三方库:

关于AVFoundation

AVFoundation 是一个很大基础库,用来创建基于时间的视听媒体,可以使用它来检查,创建、编辑或媒体文件。也可以输入流从设备和操作视频实时捕捉和回放。详细框架介绍见官网:About AV Foundation,本文只是介绍如果使用AVFoundation获取二维码。

首先获取流媒体信息我们需要AVCaptureSession对象来管理输入流和输出流,AVCaptureVideoPreviewLayer对象来显示信息

注:

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

下面看下实现过程如下:

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

#import <AVFoundation/AVFoundation.h>
实现<AVCaptureMetadataOutputObjectsDelegate>协议

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;
}

以上基本就是二维码的获取流程,和扫一扫二维码伴随的就是开启系统照明,这个比较简单,也是利用 AVCaptureDevice,请看如下实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
  - (void)systemLightSwitch:(BOOL)open
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (open) {
[device setTorchMode:AVCaptureTorchModeOn];
} else {
[device setTorchMode:AVCaptureTorchModeOff];
}
[device unlockForConfiguration];
}
}

以上就是本文介绍的大部分内容,详细代码请看demo  https://github.com/strivingboy/scan_qrcode_demo

iOS-AVFoundation实现二维码(ios7以上,转载)的更多相关文章

  1. iOS使用AVFoundation实现二维码扫描(ios7以上)——转载

    关于二维码扫描有不少优秀第三方库: ZBar SDK 里面有详细的文档,相应介绍也非常多,如:http://rdcworld-iphone.blogspot.in/2013/03/how-to-use ...

  2. iOS使用AVFoundation实现二维码扫描

    原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应 ...

  3. 【转】 iOS使用AVFoundation实现二维码扫描

    原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应 ...

  4. 微信连WiFi关注公众号流程更新 解决ios微信扫描二维码不关注就能上网的问题

    前几天鼓捣了一下微信连WiFi功能,设置还蛮简单的,但ytkah发现如果是ios版微信扫描微信连WiFi生成的二维码不用关注公众号就可以直接上网了,而安卓版需要关注公众号才能上网,这样就少了很多ios ...

  5. iOS笔记061 - 二维码的生成和扫描

    二维码 生成二维码 二维码可以存放纯文本.名片或者URL 生成二维码的步骤: 导入CoreImage框架 通过滤镜CIFilter生成二维码 1.创建过滤器 2.恢复滤镜的默认属性 3.设置内容 4. ...

  6. iOS 读取相册二维码,兼容ios7(使用CIDetector 和 ZXingObjC)

    ios从相册读取二维码,在ios8以上,苹果提供了自带的识别图片二维码的功能,这种方式效率最好,也是最推荐的,但是如果你的系统需要向下兼容ios7,就必须用其他方式. 这里我选择的是 ZXingObj ...

  7. iOS原生的AVFoundation扫描二维码/条形码

    #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVCaptureMetadataOutputO ...

  8. iOS 原生库(AVFoundation)实现二维码扫描,封装的工具类,不依赖第三方库,可高度自定义扫描动画及界面(Swift 4.0)

    Create QRScanner.swift file // // QRScanner.swift // NativeQR // // Created by Harvey on 2017/10/24. ...

  9. ios 中生成二维码和相册中识别二维码

    iOS 使用CIDetector扫描相册二维码.原生扫描 原生扫描 iOS7之后,AVFoundation让我们终于可以使用原生扫描进行扫码了(二维码与条码皆可)AVFoundation可以让我们从设 ...

随机推荐

  1. ubuntu 18.04 enp8s0更改网口名称为eth0

    尝试各种方法均不成功,后参考如下方法终于成功: 方法一:单纯改网卡名,重启后显示原网卡名. 如我的网卡名是enp8s0 >> ip link set enp8s0 down //关闭网卡 ...

  2. MVVM框架(Vue)

    问题: 一:说一下使用 JQuery和使用框架的区别? 二: 说一下对 MVVM的理解 三: Vue中如何实现响应式 四: vue中如何解析模板 五:vue整个实现流程 1. 说一下使用 JQuery ...

  3. 一步一步学会preload和prefetch

    preload和prefetch是什么? 我们常说的preload和prefetch,是link标签rel里新增的两种值,用于让浏览器提前加载指定的资源,它们会先被缓存(属于http cache缓存) ...

  4. 行内元素进行绝对(absolute),固定(fixed)定位后会变成块级元素·

    行内元素进行绝对定位后会变成块级元素· position:absolute; <!DOCTYPE html><html lang="en"><head ...

  5. Chrome浏览器设置自动启用Flash插件

    Chrome浏览器设置自动启用Flash插件   1.打开Chrome浏览器,输入chrome://flags/#run-all-flash-in-allow-mode,打开,找到Enable Eph ...

  6. mkfs/mk2fs/fsck/e2fsck/tune2fs/blkid

    mkfs 格式化创建Linux文件系统的工具 centos 6 使用xfs文件系统 fsck 检测及修复文件系统的工具 当磁盘出现逻辑错误的时候,可以尝试修复. fsck -t ext2|ext3 / ...

  7. luogu P4859 已经没有什么好害怕的了

    嘟嘟嘟 题中给的\(k\)有点别扭,我们转换成\(a > b\)的对数是多少,这个用二元一次方程解出来是\(\frac{n + k}{2}\). 然后考虑dp,令\(dp[i][j]\)表示前\ ...

  8. mac charles 代理https

    1.安装根证书:help - ssl proxying - install charles root certificate 2.这时候会弹出一个根证书界面,如果没有弹出,则可以去chrome,高级设 ...

  9. Linux之文件通信

    /* * 后执行,尝试读取另外一个进程写入文件的内容 */ #include <stdio.h> #include <unistd.h> #include <stdlib ...

  10. 查询Linux下文件格式.

    备忘 file 命令可以查一个文件的格式 readelf -h 可执行文件名. 可以查询可执行文件的详细的格式 向Windows中exeinfo 软件类