文档章节

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

 业界小白
发布于 2016/11/15 17:52
字数 1133
阅读 56
收藏 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
博文 55
码字总数 59493
作品 0
洛阳
iOS工程师
私信 提问
iOS - QRCode 二维码

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

仟0123
2016/09/15
0
0
使用AVFoundation读取二维码

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

蹲瓜
2017/12/30
0
0
AVFoundation扫描二维码,条形码

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

HillYoung
2015/12/11
1K
0
Swift AVFoundation 二维码扫描和生成

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

humingtao2013
2015/06/26
0
0
Swift_iOS: 扫描二维码的方法

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

刘传君
2017/09/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java 如何实现线程间通信?

正常情况下,每个子线程完成各自的任务就可以结束了。不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了。 本文涉及到的知识点: thread.join(), object....

颖辉小居
35分钟前
2
0
记一次阿里云服务器运行慢排除

公司测试环境用的阿里云服务器+docker部署的,一共跑了14个项目。之前几个月一直OK,最近几天突然很卡很慢。刚开始以为是项目问题,又是扩大内存,又是清减插件,甚至停了一半项目。结果CPU...

李玉长
35分钟前
2
0
统一客服消息返回错误:{"errcode":43004,"errmsg":"require subscribe hint: [9Vv08633952]"}

公众号或者小程序发送客服消息错误: {"errcode":43004,"errmsg":"require subscribe hint: [9Vv08633952]"} 场景:小程序使用公众号的服务消息,推送消息,如果接收人没有关注公众号,就会出...

tianma3798
47分钟前
1
0
Rainbond V5.0 Beta公测公告

Rainbond支撑企业应用的开发、架构、交付和运维的全流程,通过“无侵入”架构无缝衔接各类企业应用,底层资源可以对接和管理IaaS、虚拟机和物理服务器 Rainbond V5.0即日起开启Beta版本公测,...

好雨云帮
今天
2
0
Word Pattern(leetcode290)

Given a pattern and a string str, find if str follows the same pattern. Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empt......

woshixin
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部