iOS 二维码学习过程

二维码生成

生成二维码需要导入CoreImage框架,通过滤镜CIFilter生成二维码。
二维码的容错
二维码都有一定的纠错,就是有部分污损或者破损都没有关系,照常识别。但是也是有限度的
这根据生成时使用的纠错级别而定,可以有7%~%30左右的损坏(大致),实际上保守一点更好。
基本原则:
1、三个角上的“回”及“回”字周围的底色不要动
2、中间部分和不带“回”字的一角是可以填图片的(中间最好)
3、如果中间有小的“回”字,能不变就不变,能少变就少变
4、尽可能放大二维码后再添加图片,不要添加图片后放大
5、生成时尽量选择较高的纠错级别

1、最原始的生成二维码的步骤

代码实现

 //1、创建过滤器
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    //2、恢复默认
    [filter setDefaults];
    //3、给过滤器添加数据
    NSString *dataString = @"你好,河南";
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    //4、通过KVO设置路径InputMessage数据
    [filter setValue:data forKey:@"inputMessage"];
    //5、获取输出二维码
    CIImage *outPutImage = [filter outputImage];
    //6、将CIImage转换为UIImage
    _imageView.image = [UIImage imageWithCIImage:outPutImage];

效果图
iOS 二维码学习过程_第1张图片
屏幕快照 2017-02-10 下午2.39.46.png

默认情况下生成的图片比较模糊,所以需要我们重新绘制一下

2、清晰二维码

 //二维码过滤器
    CIFilter *qrImageFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //设置过滤器默认属性 (老油条)
    [qrImageFilter setDefaults];
    
    //将字符串转换成 NSdata (虽然二维码本质上是 字符串,但是这里需要转换,不转换就崩溃)
    NSData *qrImageData = [@"你看我帅不帅" dataUsingEncoding:NSUTF8StringEncoding];
    
    //我们可以打印,看过滤器的 输入属性.这样我们才知道给谁赋值
    NSLog(@"%@",qrImageFilter.inputKeys);
    /*
     inputMessage,        //二维码输入信息
     inputCorrectionLevel //二维码错误的等级,就是容错率
     */
    
    
    //设置过滤器的 输入值  ,KVC赋值
    [qrImageFilter setValue:qrImageData forKey:@"inputMessage"];
    
    //取出图片
    CIImage *qrImage = [qrImageFilter outputImage];
    
    //但是图片 发现有的小 (27,27),我们需要放大..我们进去CIImage 内部看属性
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
    
    
    self.imageView.image = [UIImage imageWithCIImage:qrImage];
    //    self.imageView.image = [UIImage imageWithCIImage:qrImage scale:100.0 orientation:UIImageOrientationUp];
    
    
    
    //    //如果还想加上阴影,就在ImageView的Layer上使用下面代码添加阴影
    
    self.imageView.layer.shadowOffset=CGSizeMake(0, 5);//设置阴影的偏移量
    
    self.imageView.layer.shadowRadius=1;//设置阴影的半径
    
    self.imageView.layer.shadowColor=[UIColor redColor].CGColor;//设置阴影的颜色为黑色
    
    self.imageView.layer.shadowOpacity=0.3;
效果图
iOS 二维码学习过程_第2张图片
屏幕快照 2017-02-10 下午3.24.16.png

3、生成彩色二维码

彩色二维码,虽然显得高大上一些,但是由于容错率相对比较低(就是不容易读出来),所以市面上还是比较少的.

  NSArray *filterArr = [CIFilter filterNamesInCategories:@[kCICategoryBuiltIn]];   //对
    
    NSLog(@"%@",filterArr); //所有内建过滤器,找CR... 二维码的
    
    //创建二维码过滤器
    CIFilter * qrfilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //设置默认属性(老油条)
    [qrfilter setDefaults];
    
    //我们需要给 二维码过期器 设置一下属性,给它一些东西,让它去生成图片吧,那些属性呢,跳进去看
    NSLog(@"%@",qrfilter.inputKeys);
    /*
     inputMessage,            //二维码的信息
     inputCorrectionLevel     //二维码的容错率 ()到达一定值后,就不能识别二维码了
     */
    
    //我们需要给 二维码 的 inputMessage 设置值,  这是私有属性,我们 使用KVC.给其私有属性赋值
    
    //将字符串转为NSData,去获取图片
    NSData * qrimgardata = [@"http://www.baidu.com" dataUsingEncoding:NSUTF8StringEncoding];
    
    //去获取对应的图片(因为测试,直接用字符串会崩溃)
    [qrfilter setValue:qrimgardata forKey:@"inputMessage"];
    
    //去获得对应图片 outPut
    CIImage *qrImage = qrfilter.outputImage;
    
    //图片不清除,打印知道其 大小 为 (27,27). 进入 CIImage,看属性,
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
    
    
    //创建彩色过滤器   (彩色的用的不多)-----------------------------------------------------
    CIFilter * colorFilter = [CIFilter filterWithName:@"CIFalseColor"];
    
    //设置默认值
    [colorFilter setDefaults];
    
    //同样打印这样的 输入属性  inputKeys
    NSLog(@"%@",colorFilter.inputKeys);
    /*
     inputImage,   //输入的图片
     inputColor0,  //前景色
     inputColor1   //背景色
     */
    
    //KVC 给私有属性赋值
    [colorFilter setValue:qrImage forKey:@"inputImage"];
    
    //需要使用 CIColor
    [colorFilter setValue:[CIColor colorWithRed:1 green:0 blue:0.8] forKey:@"inputColor0"];
    [colorFilter setValue:[CIColor colorWithRed:0 green:1 blue:0.4] forKey:@"inputColor1"];
    
    //设置输出
    CIImage *colorImage = [colorFilter outputImage];
    
    
    _imageView.image = [UIImage imageWithCIImage:colorImage];

效果图

iOS 二维码学习过程_第3张图片
屏幕快照 2017-02-10 下午3.34.16.png

4、中间加logo二维码

  //
    NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
    NSLog(@"%@",filters);
    
    //二维码过滤器
    CIFilter *qrImageFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    //设置过滤器默认属性 (老油条)
    [qrImageFilter setDefaults];
    
    //将字符串转换成 NSdata (虽然二维码本质上是 字符串,但是这里需要转换,不转换就崩溃)
    NSData *qrImageData = [@"你好,我爱你" dataUsingEncoding:NSUTF8StringEncoding];
    
    //我们可以打印,看过滤器的 输入属性.这样我们才知道给谁赋值
    NSLog(@"%@",qrImageFilter.inputKeys);
    /*
     inputMessage,        //二维码输入信息
     inputCorrectionLevel //二维码错误的等级,就是容错率
     */
    
    
    //设置过滤器的 输入值  ,KVC赋值
    [qrImageFilter setValue:qrImageData forKey:@"inputMessage"];
    
    //取出图片
    CIImage *qrImage = [qrImageFilter outputImage];
    
    //但是图片 发现有的小 (27,27),我们需要放大..我们进去CIImage 内部看属性
    qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
    
    //转成 UI的 类型
    UIImage *qrUIImage = [UIImage imageWithCIImage:qrImage];
    
    
    //----------------给 二维码 中间增加一个 自定义图片----------------
    //开启绘图,获取图形上下文  (上下文的大小,就是二维码的大小)
    UIGraphicsBeginImageContext(qrUIImage.size);
    
    //把二维码图片画上去. (这里是以,图形上下文,左上角为 (0,0)点)
    [qrUIImage drawInRect:CGRectMake(0, 0, qrUIImage.size.width, qrUIImage.size.height)];
    
    
    //再把小图片画上去
    UIImage *sImage = [UIImage imageNamed:@"龙之母.jpg"];
    
    CGFloat sImageW = 100;
    CGFloat sImageH= sImageW;
    CGFloat sImageX = (qrUIImage.size.width - sImageW) * 0.5;
    CGFloat sImgaeY = (qrUIImage.size.height - sImageH) * 0.5;
    
    [sImage drawInRect:CGRectMake(sImageX, sImgaeY, sImageW, sImageH)];
    
    //获取当前画得的这张图片
    UIImage *finalyImage = UIGraphicsGetImageFromCurrentImageContext();
    
    //关闭图形上下文
    UIGraphicsEndImageContext();
    
    
    
    //设置图片
    self.logoImageView.image = finalyImage;

效果图

iOS 二维码学习过程_第4张图片
屏幕快照 2017-02-10 下午3.58.56.png

二维码扫描

1.原生扫描用到的几个类

@property (strong,nonatomic)AVCaptureDevice * device;
@property (strong,nonatomic)AVCaptureDeviceInput * input;
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
@property (strong,nonatomic)AVCaptureSession * session;
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;

2.在viewDidLoad里创建它们

// Device
_device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

// Input
_input = [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:nil];

// Output
_output = [[AVCaptureMetadataOutputalloc]init];
[_outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

// Session
_session = [[AVCaptureSessionalloc]init];
[_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

3、连接输入和输出

if ([_sessioncanAddInput:self.input])
{
    [_sessionaddInput:self.input];
}

if ([_sessioncanAddOutput:self.output])
{
    [_sessionaddOutput:self.output];
}

4、设置条码类型

_output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];

5、添加扫描画面

_preview =[AVCaptureVideoPreviewLayerlayerWithSession:_session];
_preview.videoGravity =AVLayerVideoGravityResizeAspectFill;
_preview.frame =self.view.layer.bounds;
[self.view.layerinsertSublayer:_previewatIndex:0];

6、开始扫描

[_sessionstartRunning];

7、最后实现协议AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
   NSString *stringValue;
   if ([metadataObjectscount] >0){
   //停止扫描
   [_sessionstopRunning];        
   AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex:0];
   stringValue = metadataObject.stringValue;        
  }
}

这里就是可以成功扫描二维码了,但是这是个全屏,不太好看,需要我们设置一下扫描范围

关键代码
// 设置扫描范围(每一个取值0~1,以屏幕右上角为坐标原点)
    // 注:微信二维码的扫描范围是整个屏幕,这里并没有做处理(可不用设置)
    output.rectOfInterest = CGRectMake(0.05, 0.2, 0.7, 0.6);

参考:http://www.cocoachina.com/ios/20161009/17696.html

你可能感兴趣的:(iOS 二维码学习过程)