ios7后二维码的生成与扫描(需要注意滤镜的模糊度问题)

来源:互联网 发布:java什么是进程和线程 编辑:程序博客网 时间:2024/06/16 19:33
////  ViewController.m//  thiredEnter////  Created by michael on 15/12/6.//  Copyright (c) 2015年 MD. All rights reserved.//#import "ViewController.h"#import <AVFoundation/AVFoundation.h>@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>//用于生成二维码的图片@property (nonatomic, strong) UIImageView *imageView;//用于扫描二维码的按钮@property (nonatomic, strong) UIButton *scanfQRCodeBtn;//用于链接输入和输出流的管道@property (nonatomic, strong) AVCaptureSession *session;//用于把输出流显示在界面上的 layer@property (nonatomic, strong) AVCaptureVideoPreviewLayer *layer;@end@implementation ViewController//扫描按钮懒加载-(UIButton *)scanfQRCodeBtn{    if (!_scanfQRCodeBtn) {                _scanfQRCodeBtn = [[UIButton alloc] init];    }    return _scanfQRCodeBtn;}//图片对象懒加载-(UIImageView *)imageView{    if (!_imageView) {        //二维码肯定是正方形的,所以宽高要相等        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 150, 150)];    }    return _imageView;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    self.view.backgroundColor = [UIColor yellowColor];        [self.view addSubview:self.imageView];        [self createStr];        [self scanfStr];}//生成二维码-(void)createStr{        //二维码的实际原理: 字符串 -转-> 图片 的过程    //1.生成字符串    NSString *str = @"教师咧来说快点交罚款了速度加福禄寿的开发快了速度交罚款了速度交罚款蓝色地方了开始的减肥";        //2.字符串转为 二进制数据类型    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];        //3.创建一个滤镜--可以把二进制类型转为其他类型    //根据参数的不同,提供不同的功能    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];        //4.设置 filter相关属性    //4.1 为filter 传入要操作的数据    [filter setValue:data forKey:@"inputMessage"];        //4.2设置 filter 容错等级    [filter setValue:@"M" forKey:@"inputCorrectionLevel"];        //5.输出图片,是 CIImage 类型    CIImage *ciImg = filter.outputImage;        //6.把 CIImage 转为 UIImage    UIImage *img = [UIImage imageWithCIImage:ciImg];        self.imageView.image = img;    }//扫描二维码功能(需真机测试)-(void)scanfStr{        _scanfQRCodeBtn = [UIButton buttonWithType:0];        [_scanfQRCodeBtn setTitle:@"扫描二维码" forState:0];        _scanfQRCodeBtn.frame = CGRectMake(20, 200, 100, 40);        _scanfQRCodeBtn.backgroundColor = [UIColor lightGrayColor];        [_scanfQRCodeBtn addTarget:self action:@selector(scanQRCode:) forControlEvents:(UIControlEventTouchUpInside)];        [self.view addSubview:self.scanfQRCodeBtn];}//点击事件-(void)scanQRCode:(UIButton *)sender{    /*创建扫描二维码流程     1.打开后置摄像头,创建数据的输入流.实时获取摄像头中的数据     2.创建输出流,把摄像头录入的数据 输出到 屏幕上     3.输入流 和 输出流 之间需要一个管道进行沟通     4.实时监测输入流的数据,查看是否有二维码/条形码     5.如果摄像数据中,有二维码/条形码 则通知我们 (代理)     */        //为了使用摄像头,需要引入 AVFoundation框架 及其 .h 文件    //1.获取设备摄像头对象    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];        //2.从摄像头获取输入流    NSError *error = nil;    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];        if (error) {        NSLog(@"input error %@",error);        //如果出错,直接返回        return;    }        //3.创建输出流---用于输出影像到屏幕上    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];        //3.1 扫描到二维码 或者 条形码的 代理,代理方法在主线程中执行    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];        //4.0 创建管道    _session = [[AVCaptureSession alloc] init];        //4.1 为管道添加输入流    [_session addInput:input];        //4.2 为管道添加输出流    [_session addOutput:output];        //4.3 管道质量,高品质的输出(可选) .  流畅,高清,超清,原画    [_session setSessionPreset:AVCaptureSessionPresetHigh]; //最高质量的输出        //4.4 设置扫描的数据类型 :二维码 + 条形码,扫描数据的类型必须写在添加到管道之后    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode , AVMetadataObjectTypeEAN8Code ,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeCode128Code];        //5.把管道中的图像读取出来    _layer = [AVCaptureVideoPreviewLayer layerWithSession:_session];        //5.1 设置layer 的大小,frame    _layer.frame = self.view.frame; //全屏        //5.2 设置layer 中的图片是铺满状态    _layer.videoGravity = AVLayerVideoGravityResizeAspectFill;        //5.3 把 layer 添加到屏幕上    [self.view.layer addSublayer:_layer];        //6.0 启动管道    [_session startRunning];}#pragma mark - OutPutDelegate//扫描数据成功后,自动进入下方协议方法-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{        if (metadataObjects.count > 0) {        //扫描到数据: 关闭管道,移除扫描的图像        [_session stopRunning];        [_layer removeFromSuperlayer];                //把扫描到的数据拿出来        AVMetadataMachineReadableCodeObject *obj = metadataObjects.firstObject; //取到数组中的第一个元素        NSLog(@"扫描到的二维码 或者 条形码 是 %@",obj.stringValue);                //一般扫描完后获取网络数据,然后根据网络地址跳转到相关页面(下载页面或更多)    }    }/* 注意:获取数组的第一个元素 有两种方式 arr[0]      arr.firstObject 这两种方式不一样,如果是一个 @[]数组,即空数组,使用 arr[0] 会因为数组越界崩溃,而另一种方法不会  */- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end

0 0
原创粉丝点击