zoukankan      html  css  js  c++  java
  • 二维码生成与扫描

    偶尔用这一块的东西,总是记不住,所以写了两个demo 注释写的非常详细.

    二维码的生成:

    #import "ViewController.h"
    #import <CoreImage/CoreImage.h>
    
    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UIImageView *codeImage;
    
    @end
    
    
    /*
     1. 生成二维码 要导入CoreImage 这个系统原生框架 (因为要去获取内置滤镜 支持各种种类的二维码)
     
     2.
     (
     inputMessage,  链接的字符串  (输入的 就是咱们自己去设定的)
     inputCorrectionLevel   链接类型
     )
    
     3. 要记住 扫二维码 是一个操作 根据得到的这个字符串的类型 去让他去做下一步的操作.
     
     4.filter.outputImage 得到图片
     
     5.调整清晰度
     
     
     */
    @implementation ViewController
    
    - (void)viewDidLoad {
        
        [super viewDidLoad];
      
        // 1. 创建滤镜对象  内置滤镜 支持各种种类的二维码 跟一个类型 具体什么格式 不清楚
          // 通过一个分类的属性 来进行打印 打印所有的对象
       // NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryBuiltIn]);
          // 二维码滤镜已经获取
        CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
        
        // 2. 设置默认值
        [filter setDefaults];
        
        // 3.输入字符串
        NSLog(@"%@",filter.inputKeys);  // 完全可以吧这个字符串去看做是一个特殊的字符串类型
        
        // 只读属性 利用KVC 进行复制
        // CIQRCodeGenerator filter requires NSData for inputMessage 这个哥们必须是一个二维码
        // 将字符串 转换成2进制的方法
        [filter setValue:[@"http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html" dataUsingEncoding:NSUTF8StringEncoding]
                  forKey:@"inputMessage"];
        
         NSLog(@"%@",filter.inputKeys);
        
        // 5.放大图片 CIImage 是继承自NSObject (原因:CIImage 确实是放大了五倍,然后CodeImageFrame没有改变,像素点密集 变得清晰)
        CIImage *resultImage = [filter.outputImage imageByApplyingTransform:CGAffineTransformMakeScale(5, 5)];
        self.codeImage.image = [UIImage imageWithCIImage:resultImage];
        
    //    // 4.获取二维码的图片
    //    CIImage *imageC = filter.outputImage;
    //    
    //    self.codeImage.image = [UIImage imageWithCIImage:imageC];
    //    
    }
    
    @end

    二维码的读取:

    #import "ViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
    
    @property (nonatomic,strong)AVCaptureSession *session;
    
    @property (nonatomic,strong)AVCaptureDeviceInput *input;
    
    @property (nonatomic,strong)AVCaptureMetadataOutput *output;
    
    // 创建预览视图  layer层 专门用来显示输入设备来捕捉到的画面
    @property (nonatomic,strong)AVCaptureVideoPreviewLayer *viewLayer; // 继承自CALayer
    
    @end
    
    /*
     1.导入AVFoundtation 框架
     
     输入设备 相机  麦克 键盘等   AVCaptureDeviceInput(子类)    AVCaptureInput(父类)
    
     输出设备  解析  (元数据) AVCaptureMetadataOutput -> AVCaptureOutput
     
     会话链接  将输入设备和输出设备去建立联系
     
     二维码的扫码和屏幕显示的东西都是没有关系的,只是和摄像头对准的二维码有关 至于后来的页面跳转和别的操作 就是其他的业务逻辑 咱们只是拿到数据之后 对这个字符串去进行分析 格式
     
     元数据: 元数据(MetaData)
         因为它们是用来描述具体数据/信息的数据/信息。
         在日常生活中,元数据无所不在。有一类事物,就可以定义一套元数据。
         元数据最大的好处是,它使信息的描述和分类可以实现格式化,从而为机器处理创造了可能。
     
     1. 创建输入设备对象 AVCaptureDeviceInput 并且设置好设备类型
     
     2,创建输出设备对象 AVCaptureMetadataOutput (元数据对象)
     
     3. 创建 AVCaptureSession 对象 将输入输出(添加)建立联系
     
     4. 设置视频范围   [self.session setSessionPreset:AVCaptureSessionPresetHigh];
     
     5.开启
     
     6,设置 AVCaptureMetadataOutput 的数据 并获取对象.. (
     
     7. 设置输出设备的类型 (注意 有坑)
     
     
     */
    
    /*
     输出设备的与数据得到可用参数
     (
     "org.iso.Aztec",
     "org.iso.Code128",
     "org.iso.Code39",
     "org.iso.Code39Mod43",
     "com.intermec.Code93",
     "org.iso.DataMatrix",
     "org.gs1.EAN-13",
     "org.gs1.EAN-8",
     "org.ansi.Interleaved2of5",
     "org.gs1.ITF14",
     "org.iso.PDF417",
     "org.iso.QRCode",    二维码 类型
     "org.gs1.UPC-E",
     face
     )
     */
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        
        [super viewDidLoad];
    }
    
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        
        // 1 创建输入设备 (类型为相机)
         // 给定一个设备 让咱们知道是哪个设备 AVMediaTypeVideo  就是这个样式的的字符串 ??
        // 元数据
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        self.input  = [[AVCaptureDeviceInput alloc]initWithDevice:device error:nil];
        
        
        // 2, 创建输出设备  用来去解析
        self.output = [[AVCaptureMetadataOutput alloc]init]; // ??
        // 2,1 设置输出设备的代理  (这个地方的代理设置的地放比较特殊) // 这个地方为什么要去设置一个全局队列
        [ self.output setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(0, 0)];
        
        
    //    //6. 设置元数据类型区别的
    //    // 先去打印一下可用类型有哪些 (7.0 之前 和7.0 之后  这个地方是有)
    //    NSLog(@"%@",self.output.metadataObjectTypes); // 元数据可以利用的数据类型
    //    
        
        // 3. 创建会话层  建立联系
        
        self.session  =  [[AVCaptureSession alloc]init];
        
        // 3.1 先判断能否添加 设备  然后添加
        
        if ([self.session canAddInput:self.input]) {
            
            [self.session addInput:self.input];
        }
        if ([self.session canAddOutput:self.output]) {
            [self.session  addOutput:self.output];
        }
        
        // 5, 设置视频范围
        //[self.session setSessionPreset:AVCaptureSessionPresetHigh];
        // high  是自适应的
        [self.session setSessionPreset:AVCaptureSessionPresetHigh];
        
        
        //6. 设置元数据类型
        // 先去打印一下可用类型有哪些
        NSLog(@"%@",self.output.availableMetadataObjectTypes); // 元数据可以利用的数据类型
         // 根据类型去进行设置
        [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
       
         // 4. 开启会话
        [self.session startRunning];
        
        // 8. 增加一个预览视图 用来去显示输入设备的画面
           // 创建
        self.viewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
          // 设置frame
        self.viewLayer.frame = self.view.bounds;
       // [self.view addSubview:self.viewLayer];   继承自CALayer
        [self.view.layer addSublayer:self.viewLayer];
        
    }
    
    #pragma mark -- 代理的方法 解析数据的时候就会去调用这个方法
    // 数据解析完成之后 会给你返回一个字符串
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
        // 扫描的数据全部都放在 metadataObjects 既然是数组 那么久先去打印他
        //NSLog(@"%@",metadataObjects);
        //取出扫描的数据
        AVMetadataMachineReadableCodeObject *objc = [metadataObjects firstObject];
        NSLog(@"%@",objc.stringValue);
        // 关闭会话
        [self.session stopRunning];
        // 移除这个层
        [self.viewLayer removeFromSuperlayer];
    }
    
    
    @end
  • 相关阅读:
    UVA 10600 ACM Contest and Blackout(次小生成树)
    UVA 10369
    UVA Live 6437 Power Plant 最小生成树
    UVA 1151 Buy or Build MST(最小生成树)
    UVA 1395 Slim Span 最小生成树
    POJ 1679 The Unique MST 次小生成树
    POJ 1789 Truck History 最小生成树
    POJ 1258 Agri-Net 最小生成树
    ubuntu 用法
    ubuntu 搭建ftp服务器,可以通过浏览器访问,filezilla上传文件等功能
  • 原文地址:https://www.cnblogs.com/zhubaofeng/p/5433316.html
Copyright © 2011-2022 走看看