文档章节

AVFoundation框架实现二维码的扫描、二维码的生成

 业界小白
发布于 2016/11/15 17:52
字数 1133
阅读 38
收藏 0
点赞 0
评论 0

AVFoundation框架简单介绍:用来完成拍照和录制视频功能

AVFoundation框架的常用类:

AVCaptureDevice :该对象代表物理输入设备,包括摄像头和麦克风.开发者可通过该对象来配置底层物理设备的属性.需要指出的是,

我们不能直接创建该类的实例,只能通过该类的 devices、defaultDeviceWithMediaType:(NSString *)mediaType、devicesWithMediaType:(NSString *)mediaType方法 来获取对应的输入设备数组,接下来即 可获取前置摄像头、后置摄像头或麦克风。

AVCaptureSession :该对象负责把AVCaptureDevice捕捉得到的视频或声音数据输出到输出设备中.不管执行实时的还是离线的录制,开发者都必须创建AVCaptureSession对象,并为该对象添加输入设备(负责捕捉数据)和输出端(负责接收数据).

AVCaptureDeviceInput  :它是AVCaptureInput的子类,使用该对象从AVCaptureDevice设备获取数据,该对象将会被添加给AVCaptureSession管理.

AVCaptureScreenInput :它是AVCaptureInput的子类,使用该对象从屏幕获取数据(用于录制屏幕动作).该对象将会被添加给AVCaptureSeesion管理

AVCaptureAudioDataOutput、AVCaptureAudioPreviewOutput、AVCaptureFileOutput 、AVCaptureStillImageOutput、AVCaptureVideoDataOutput:它们都是AVCaptureOutput的子类,用于接收各种数据.该对象也会被添加给AVCaptureSession管理.其中AVCaptureFileOutput依然代表输出到文件的输出端,

AVCaptureAudioFileOutput 、AVCaptureMovieFileOutput :它们都是AVCaptureFileOutput的子类,分别代表输出到音频文件、电影文件的输出端。

AVCaptureVideoPreviewLayer:该对象是CALayer的子类,开发者只要创建它的实例,并为它设置AVCaptureSession,就可以非常方便地用它来实现拍摄预览.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

二维码的扫描:

 // 获取摄像输入设备
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        // 创建输入流
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        if (!input) {
            return nil;
        }
        
        // 创建输出流
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
        // 设置代理 在主线程里刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        // 设置扫描区域的frame
//        CGFloat width = 300 / CGRectGetHeight(self.view.frame);
//        CGFloat height = 300 / CGRectGetWidth(self.view.frame);
        /* 假如你的屏幕的frame 为  x , y,  w, h,  你要设置的矩形快的frame  为  x1, y1, w1, h1.   那么你的 rectOfInterest 应该设置为   CGRectMake(y1/y, x1/x, h1/h, w1/w)
         */
//        output.rectOfInterest = CGRectMake((1-width)/2, (1-height)/2, width, height);
        
        AVCaptureSession *session = [[AVCaptureSession alloc] init];
        // 设置为高质量采集率
        [session setSessionPreset:AVCaptureSessionPresetHigh];
        [session addInput:input];
        [session addOutput:output];
        
#warning 必须先添加到session然后才能设置,否则会崩溃
        // 设置扫码支持的编码格式(这里设置条形码和 二维码兼容)
        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
                                       AVMetadataObjectTypeEAN13Code,
                                       AVMetadataObjectTypeEAN8Code,
                                       AVMetadataObjectTypeCode128Code];
// 创建一个预览层
    AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    /* AVLayerVideoGravityResizeAspect 保持视频的宽高比并使播放内容自动适应播放窗口的大小。
     * AVLayerVideoGravityResizeAspectFill 以播放内容填充而不是适应播放窗口的大小。
     * AVLayerVideoGravityResize  会拉伸播放内容以适应播放窗口。
     */
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    layer.frame = self.view.layer.bounds;
    [self.view.layer insertSublayer:layer atIndex:0];
#pragma mark - 输出流的代理(扫描结果)
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    
    if (metadataObjects.count > 0) {
        
        // 停止扫描
        [self.session stopRunning];
        
        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects firstObject];
        NSLog(@"扫描结果:%@", metadataObject.stringValue);
        
        [self showAlertWithTitle:@"查询结果" message:metadataObject.stringValue handler:^(UIAlertAction *action) {
            
            [self.session startRunning];
            
        }];
        
        
    }
    
    
}
// 开关闪光灯(操作前必须锁定)
- (void)shan{
    self.isOpen = !self.isOpen;
    
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    // 判断闪光灯是否能用
    if ([device hasTorch]) {
        // 加锁
        [device lockForConfiguration:nil];
        if (self.isOpen) {
            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭闪光灯" style:UIBarButtonItemStylePlain target:self action:@selector(shan)];
            
            device.torchMode = AVCaptureTorchModeOn;
            
        }else{
            
            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"打开闪光灯" style:UIBarButtonItemStylePlain target:self action:@selector(shan)];
            device.torchMode = AVCaptureTorchModeOff;
        }
        // 解锁
        [device unlockForConfiguration];
    }
    
}

二维码生成:(黑白色)

- (UIImage *)creatImageWithString:(NSString *)string size:(CGSize)size{
    
    // 创建滤镜
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    // 还原默认设置(清空滤镜,因为滤镜有可能保存上一次的设置)
    [filter setDefaults];
    // 创建二维码需要保存的数据
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    // 设置数据
    [filter setValue:data forKey:@"inputMessage"];
    // 生成二维码,获取生成后的二维码图片
    CIImage *image = [filter outputImage];
    
    // 放大并绘制二维码(上面生成的二维码很小,需要放大)
    CGImageRef imageRef = [[CIContext contextWithOptions:nil] createCGImage:image fromRect:image.extent];
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, kCGInterpolationNone);
    // 翻转一下图片,不然生成的QRCode就是上下颠倒的
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGContextGetClipBoundingBox(context), imageRef);
    UIImage *contextImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGImageRelease(imageRef);
    
    return contextImage;
}

改变生成的二维码的颜色(基于生成的二维码)

UIImage *image = self.imageV.image;
        
        UIGraphicsBeginImageContext(image.size);
        
        [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
        
        UIImage *img = [UIImage imageNamed:@"023"];
        
        CGFloat imageW = 50;
        CGFloat imageX = (image.size.width - imageW) * 0.5;
        CGFloat imgaeY = (image.size.height - imageW) * 0.5;
        
        [img drawInRect:CGRectMake(imageX, imgaeY, imageW, imageW)];
        
        UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        self.imageV.image = result;

在二维码中间添加个图片

UIImage *image = [self creatImageWithString:self.textF.text size:self.imageV.frame.size];
        
        UIColor *back = [UIColor blueColor];
        UIColor *font = [UIColor orangeColor];
        CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"
                                           keysAndValues:
                                 @"inputImage",[CIImage imageWithCGImage:image.CGImage],
                                 @"inputColor0",[CIColor colorWithCGColor:font.CGColor],
                                 @"inputColor1",[CIColor colorWithCGColor:back.CGColor],
                                 nil];
        
        self.imageV.image = [UIImage imageWithCIImage:colorFilter.outputImage];

 

© 著作权归作者所有

共有 人打赏支持
粉丝 1
博文 51
码字总数 53050
作品 0
洛阳
iOS工程师
iOS - QRCode 二维码

1、QRCode 在 iOS7 以前,在 iOS 中实现二维码和条形码扫描,我们所知的有,两大开源组件 ZBar 与 ZXing。iOS7 之后可以利用系统原生 API 生成二维码, iOS8 之后可以生成条形码, 系统默认生成...

仟0123 ⋅ 2016/09/15 ⋅ 0

使用AVFoundation读取二维码

二维码(Quick Response Code,简称QR Code)是由水平和垂直两个方向上的线条设计而成的一种二维条形码(barcode)。可以编码网址、电话号码、文本等内容,能够存储大量的数据信息。自iOS 7以...

蹲瓜 ⋅ 2017/12/30 ⋅ 0

IOS --自带二维码扫描

具体的可以参考这篇文章:http://www.appcoda.com/qr-code-ios-programming-tutorial/ 最近由于公司项目需要,我负责二维码的生成和扫描部分。由于苹果规定自2015/02/01后上架的作品必须支持...

求是科技 ⋅ 2015/02/26 ⋅ 0

AVFoundation扫描二维码,条形码

在使用AVFoundation之前用过,zbar,zxing来实现二维码的生成以及解析,但是未进行扫描二维码,通过查阅资料发现使用AVFoundation会更有优势。 zbar和zxing有哪些优劣势可以看看:http://ww...

HillYoung ⋅ 2015/12/11 ⋅ 0

Swift AVFoundation 二维码扫描和生成

项目终于不需要支持iOS6了(泪崩),在二维码扫描这一块,能够完全的放弃库,改用系统的了,拿写了个Demo,效果如下: github地址:点这里 有关和(滤镜等),可以先看看objc.io第21期和第23期的有关介绍...

humingtao2013 ⋅ 2015/06/26 ⋅ 0

Swift_iOS: 扫描二维码的方法

可以使用AVFoundation框架来启动相机扫描二维码,把一个二维码转换为一个字符串。 如下应用,进入首页看到一个按钮和一个标签。点按钮的话,会触发一次扫描,把扫描到的二维码转换为字符串后...

刘传君 ⋅ 2017/09/01 ⋅ 0

二维码扫描和应用跳转

前言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar。使用时集...

04zhujunjie ⋅ 2015/11/02 ⋅ 0

使用系统自带的框架完成扫描二维码、条形码,以及识别相册中的二维码

一、生成二维码(使用coreImage.framework) - (CIImage )createQRForString:(NSString )qrString { // Need to convert the string to a UTF-8 encoded NSData object NSData *stringData ......

南瓜宝宝 ⋅ 2016/05/30 ⋅ 0

使用CIFilter生成二维码

二维码(Quick Response Code,简称QR Code)是由水平和垂直两个方向上的线条设计而成的一种二维条形码(barcode)。可以编码网址、电话号码、文本等内容,能够存储大量的数据信息。自iOS 7以...

蹲瓜 ⋅ 2017/12/30 ⋅ 0

[swift3.0]-二维码扫描、生成二维码、识别二维码

贡献作者 -【XJDomain】 博客XJ: https://my.oschina.net/shengbingli/blog GitHub: https://github.com/lishengbing/XJQRCodeToolDemo 目前ZBarSDK 封装的二维码功能犹豫不再支持64位,苹果......

XJDomain ⋅ 2016/11/14 ⋅ 4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JDK1.6和JDK1.7中,Collections.sort的区别,

背景 最近,项目正在集成测试阶段,项目在服务器上运行了一段时间,点击表格的列进行排序的时候,有的列排序正常,有的列在排序的时候,在后台会抛出如下异常,查询到不到数据,而且在另外一...

tsmyk0715 ⋅ 26分钟前 ⋅ 0

spring RESTful

spring RESTful官方文档:http://spring.io/guides/gs/rest-service/ 1. 可以这么去理解RESTful:其实就是web对外提供的一种基于URL、URI的资源供给服务。不是一个原理性知识点。是一个方法论...

BobwithB ⋅ 28分钟前 ⋅ 0

C++ 中命名空间的 5 个常见用法

相信小伙伴们对C++已经非常熟悉,但是对命名空间经常使用到的地方还不是很明白,这篇文章就针对命名空间这一块做了一个叙述。 命名空间在1995年被引入到 c++ 标准中,通常是这样定义的: 命名...

柳猫 ⋅ 30分钟前 ⋅ 0

@Conditional派生注解

@Conditional派生注解(Spring注解版原生的@Conditional作用) 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效; @Conditional扩展注解 作用(判...

小致dad ⋅ 31分钟前 ⋅ 0

适配器模式

适配器模式 对象适配器 通过私有属性来实现的类适配器 通过继承来实现的接口适配器 通过继承一个默认实现的类实现的

Cobbage ⋅ 34分钟前 ⋅ 0

Java 限流策略

概要 在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃。此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速...

轨迹_ ⋅ 38分钟前 ⋅ 0

GridView和子View之间的间隙

默认的情况下GridView和子View之间会有一个间隙,原因是GridView为了在子View被选中时在子View周围显示一个框。去掉的办法如下: android:listSelector="#0000" 或 setSelector(new ColorDra...

国仔饼 ⋅ 42分钟前 ⋅ 0

idea插件开发

1 刷新页面要使用多线程 2 调试要使用restart bug 不要去关闭调试的idea 否则再次启动会卡住

林伟琨 ⋅ 42分钟前 ⋅ 0

Java 内存模型

物理机并发处理方案 绝大多数计算任务,并不是单纯依赖 cpu 的计算完成,不可避免需要与内存交互,获取数据。内存要拿到数据,需要和硬盘发生 I/O 操作。计算机存储设备与 cpu 之间的处理速度...

长安一梦 ⋅ 49分钟前 ⋅ 0

思路分析 如何通过反射 给 bean entity 对象 的List 集合属性赋值?

其实 这块 大家 去 看 springmvc 源码 肯定可以找到实现办法。 因为 spirngmvc 的方法 是可以 为 对象 参数里面的 list 属性赋值的。 我也没有看 具体的 mvc 源码实现,我这里只是 写一个 简...

之渊 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部