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

关于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. 002_C/C++笔试题_简单算法程序

    (一)冒泡排序法 #include <iostream> using namespace std; void bubblesort(int a[], int m); int main(vo ...

  2. List根据某字段去重,以及compareTo 浅解

    原文链接:https://blog.csdn.net/qq_35788725/article/details/82259013 Collections.sort可对集合进行排序 根据List里面某个字 ...

  3. 如何实现对ArrayList排序 sort()

    package com.collection; import java.util.ArrayList;import java.util.Collections;import java.util.Com ...

  4. 【深入学习Redis】Redis内存模型

    前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...

  5. 034_非交互自动生成 SSH 密钥文件

    #!/bin/bash#-t 指定 SSH 密钥的算法为 RSA 算法;-N 设置密钥的密码为空;-f 指定生成的密钥文件存放在哪里 rm -rf ~/.ssh/{known_hosts,id_rsa ...

  6. 网络_05 STP HSRP

    一.案例1:STP的基本配置 将S1配置成vlan1的主根,将S2配置成vlan2的次根 查看生成树的配置:show spanning-tree 查看某个vlan生成树的详细信息:show spann ...

  7. Self install windows service in .NET c#

    http://stackoverflow.com/questions/4144019/self-install-windows-service-in-net-c-sharp using System; ...

  8. 【线性代数】6-7:SVD分解(Singular Value Decomposition-SVD)

    title: [线性代数]6-7:SVD分解(Singular Value Decomposition-SVD) categories: Mathematic Linear Algebra keywo ...

  9. Windows 消息以及消息处理算法--线程和消息队列详解

    Windows以消息驱动的方式,使得线程能够通过处理消息来响应外界. Windows 为每个需要接受消息和处理消息的线程建立消息队列(包括发送消息队列,登记消息队列,输入消息队列,响应消息队列),其中 ...

  10. c 判断数字是否有限

    /* isfinite example */ #include <stdio.h> /* printf */ #include <math.h> /* isfinite, sq ...