美文网首页
iOS二维码扫描

iOS二维码扫描

作者: QL_fish | 来源:发表于2017-12-01 13:59 被阅读133次

公司最近要添加一个二维码扫描网页登录的功能,所以最近研究了一下iOS关于二维码扫描的功能
因为移动端不涉及二维码的生成,所以只做关于二维码的扫描(这里感谢一下SGQRCode的作者)

我们先来说说AVCaptureSession。AVCaptureSession是AVFoundation框架的核心类,用于捕捉视频和音频,协调视频和音频的输入和输出流.下面是围绕AVCaptureSession的图 5301663-fab2e80855a3ef4b.jpg

摄像头扫描二维码

用摄像头扫描二维码就需要我们刚才说的AVCaptureSession,具体怎么实现,我们来看demo。

框架

首先导入我们要用到的框架,因为扫描和识别都是在系统AVFoundation下的做的,所以第一步就要把框架主头文件导入 #import <AVFoundation/AVFoundation.h>

头文件

/** 回话对象属性*/
@property (nonatomic, strong) AVCaptureSession *session;

/** 摄像头预览图层*/
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;

实现部分

    // 创建回话对象
    self.session = [[AVCaptureSession alloc] init];
    
    // 设置回话对象图像采集率
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    
    // 获取摄像头设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    // 创建回话输入对象
    NSError *inputError = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&inputError];
    
    // 添加会话输入
    [self.session addInput:input];
    
    // 创建输出对象
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
    // 设置输出对象代理
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // 添加会话输出
    [self.session addOutput:output];
    
    // 设置输出数据类型,需要将元数据输出添加到回话后,才能制定元数据,否则会报错
    // 二维码和条形码可以一起设置
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code,  AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
    
    // 创建摄像头预览图层
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    
    self.previewLayer.frame = self.view.frame;
    
    // 将图层插入当前图层
    [self.view.layer insertSublayer:self.previewLayer atIndex:0];
    
    // 启动会话
    [self.session startRunning];

主体方法实现了以后,我们来看一下AVCaptureMetadataOutputObjectsDelegate方法- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection;,当二维码扫描成功之后,系统将自动调用这个代理方法。

AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
    // 1、如果扫描完成,停止会话
    [self.session stopRunning];
    
    // 2、删除预览图层
    [self.previewLayer removeFromSuperlayer];
    
    // 3、设置界面显示扫描结果
    if (metadataObjects && metadataObjects.count > 0) {
        // 播放音效
        NSString *audioFile = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"wav"];
        NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
        
        SystemSoundID soundID = 0;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
        AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
        AudioServicesPlaySystemSound(soundID); // 播放音效
        AVMetadataMachineReadableCodeObject *obj = metadataObjects.firstObject;
        // 取出二维码扫描到的内容
        NSLog(@"二维码内容:::%@",obj.stringValue);
    }
}
// 播放音效成功回调
void soundCompleteCallback (){
   
}

如果想监听设备摄像头实时的视频流就将会话输出对象添加AVCaptureVideoDataOutputSampleBufferDelegate代理监听实现- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection;代理方法

AVCaptureVideoDataOutputSampleBufferDelegate

[output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

实现方法

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    // 这个方法会时时调用,但内存很稳定
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    
    NSLog(@"%f",brightnessValue);
}

相关文章

  • iOS开发:二维码扫描与生成(扫描篇)

    iOS开发中经常要用到生成二维码与扫描二维码的功能,iOS7开始,系统支持原生的扫描二维码,iOS7 扫描二维码可...

  • ZBar

    iOS中使用ZBar扫描二维码自定义扫描界面

  • iOS开发之二维码扫描

    iOS开发之二维码扫描 在 iOS7 以前,在IOS中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar...

  • IOS中生成二维码、扫描二维码

    title : IOS中生成二维码、扫描二维码category : UI IOS中生成二维码、保存二维码 标签(空...

  • iOS二维码扫描

    前面我们已经学会了iOS二维码生成相关的知识,这篇文章主要是讲解一下iOS二维码扫描相关的知识. 二维码扫描步骤 ...

  • 二维码扫描和创建(上)

    扫描二维码(包括读取和解码) 扫描二维码OC的开源库有ZBar和ZXing。iOS7以后iOS拥有原生的扫码功能。...

  • 2019-06-03

    iOS二维码扫描//设置条码类型 ****.metadataObjectTypes =@[... - 简书

  • 详细易懂的二维码的扫描、识别与生成

    ios7之前我们实现二维码扫描是借助第三方(ZBar,ZXing等)来实现的,在ios7之后系统自己提供二维码扫描...

  • 二维码扫描

    来源 二维码扫描 ios7之前我们实现二维码扫描一般是借助第三方来实现,但是在ios7之后系统自己提供二维码扫面的...

  • iOS 二维码扫描

    iOS开发中 二维码扫描 前言 在移动开发中二维码扫描这种事情越来越常见了,在iOS中我选择了用ZBar这个第三方...

网友评论

      本文标题:iOS二维码扫描

      本文链接:https://www.haomeiwen.com/subject/jbmibxtx.html