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

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

关于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

时间: 2024-10-10 23:32:12

iOS使用AVFoundation实现二维码扫描(ios7以上)——转载的相关文章

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 *kScanQRCodeQu

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

原文:http://strivingboy.github.io/blog/2014/11/08/scan-qrcode/ 关于二维码扫描有不少优秀第三方库如: ZBar SDK 里面有详细的文档,相应介绍也非常多,如:http://rdcworld-iphone.blogspot.in/2013/03/how-to-use-barcode-scanner-br-and-qr-in.html ZXing google推出的开源项目,相应介绍如:http://blog.devtang.com/blo

iOS 开发之 ZBarSDK 二维码扫描自定义二维码扫描页面(二)

iOS 开发之 ZBarSDK 二维码扫描自定义二维码扫描页面(二) 上一篇解决了ZBarSDK不支持64bit的问题,下面我们就可以使用ZBarSDK了. 导入ZBarSDk.h文件 附上代码: // //  MeViewController.m //  Auditory Blog // //  Created by 寒竹子 on 15/4/28. //  Copyright (c) 2015年 寒竹子. All rights reserved. // #define ScanWidth  2

IOS二维码扫描IOS7系统实现

扫描相关类 二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话.我们需要用到一下几个类: AVCaptureSession 会话对象.此类作为硬件设备输入输出信息的桥梁,承担实时获取设备数据的责任 AVCaptureDeviceInput 设备输入类.这个类用来表示输入数据的硬件设备,配置抽象设备的port AVCaptureMetadataOutput 输出类.这个支持二维码.条形码等图像数据的识别 AVCaptureVideoPrevie

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

系统提供的AVCaptureSession仅仅适用于iOS7.0以上的系统.之前的请用Zbar来替代 下载地址:http://download.csdn.net/detail/huobanbengkui/8881097 配置project: 引入: import Foundation import AVFoundation 接受AVCaptureMetadataOutputObjectsDelegate(如: class QrcodeVC: UIViewController,AVCaptureM

使用AVFoundation完成二维码扫描

其中有几点需要注意的 1.应该使用异步线程来配置那几个属性,这样可以防止阻塞主线程加载UI. 2.output的rectOfInterst是感应区域,就是说,在这个区域内才有扫描效果.但是由于摄像头的关系,这个rect的x和y是反着的,width和height也是反着的,就是说,这里的x坐标对应着正常情况下的y坐标,这里的宽度对应着正常情况下的高度. 3.sessionPreset属性是用来设置扫描精度的. 4.metaObjectTypes属性可以设置扫描的类型,有二维码和一维码(条形码).

二维码扫描--iOS7用avfoundtion,iOS调用zbar类库

源代码下载地址:http://download.csdn.net/detail/haogaoming123/8417143

iOS 开发之 ZBarSDK 二维码扫描 静态库不支持64bit完美解决(一)

由于ZBarSDK不支持arm64 bit,下面是自己进行编译打包生成支持64bit的.a文件的方法. 首先下载ZBarSDK,解压后打开iPhone的文件夹,删除Example文件夹.然后打开zbar.xcodeproject,设置工程编译环境为Release环境. 修改Standard Achived 为armv7 arm64,然后build.注意:先选择真机build,此时不需要插入真机.然后,在选择模拟器build. 得到两个.a文件. 最后一步: 将真机下得到的.a文件和模拟器下得到的

iOS开发-二维码扫描和应用跳转

iOS开发-二维码扫描和应用跳转 序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar.使用时集成麻烦,出错也不方便调试.在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架.本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转.ps:本期的源代码会在文章结尾给出链接 扫描相关类 二维码扫描需要获取摄像头并读取