iOS生成二维码利用CoreImage

生成二维码就不是AVFoundation架构了,使用的是CoreImage。之前在航歌上面看见一篇使用Swift生成二维码的文章。看了之后,我就想想,Swift可以使用原生的,那么OC可不可以呢?经过测试是可以的,而且可以生成带logo的。使用起来也很简单。

首先看看两种图片:


左右两张图,都是同一个二维码,可以扫扫,有惊喜的。

左边的一张看起来模糊,右边的看起来清晰多了,这又是为什么呢?下面就会有解答的。

怎么生成二维码:

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  *  根据字符串生成二维码 CIImage 对象 
  3.  * 
  4.  *  @param urlString 需要生成二维码的字符串 
  5.  * 
  6.  *  @return 生成的二维码 
  7.  */  
  8. + (CIImage *)creatQRcodeWithUrlstring:(NSString *)urlString{  
  9.     // 1.实例化二维码滤镜  
  10.     CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];  
  11.     // 2.恢复滤镜的默认属性 (因为滤镜有可能保存上一次的属性)  
  12.     [filter setDefaults];  
  13.     // 3.将字符串转换成NSdata  
  14.     NSData *data  = [urlString dataUsingEncoding:NSUTF8StringEncoding];  
  15.     // 4.通过KVO设置滤镜, 传入data, 将来滤镜就知道要通过传入的数据生成二维码  
  16.     [filter setValue:data forKey:@"inputMessage"];  
  17.     // 5.生成二维码  
  18.     CIImage *outputImage = [filter outputImage];  
  19.     return outputImage;  
  20. }  
生成的时CIImage对象,在显示的时候还需要先转换为UIImage对象。

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. CIImage *ciImage = [RadiusImage creatQRcodeWithUrlstring:@"http://blog.csdn.net/zhuming3834"];  
  2. UIImage *im = [UIImage imageWithCIImage:ciImage];  
  3. self.imageView.image = im;  
这样就生成了上面图片的左边那一张二维码。

为什么会模糊呢?

我们可以打印一下生成的图片的size:

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. NSLog(@"im.size.height = %f,im.size.width = %f",im.size.height,im.size.width);  
  2. // im.size.height = 31.000000,im.size.width = 31.000000  
生成的二维码图片的大小是31x31,而我们的控件imageView的大小是180x180。原来是图片被拉伸了导致的模糊。

怎么解决这个问题呢?

写在这里的时候,想起了一个方法:

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. im = [im stretchableImageWithLeftCapWidth:im.size.height/2 topCapHeight:im.size.width/2];  
  2. self.imageView2.image = im;  
这个是拉伸图片的,有没有作用呢?先测试一下看看。上图:


这是什么啊?上面的方法确实是拉伸图片,但是它使用图片的中心点开始拉伸,图片里面的元素也被拉伸了(向四周扩展了,而被挤到了一起)。很显然这个方法不能使用。那么有没有更好的方法呢?答案是有的。

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  *  改变图片大小 (正方形图片) 
  3.  * 
  4.  *  @param ciImage 需要改变大小的CIImage 对象的图片 
  5.  *  @param size    图片大小 (正方形图片 只需要一个数) 
  6.  * 
  7.  *  @return 生成的目标图片 
  8.  */  
  9. + (UIImage *)changeImageSizeWithCIImage:(CIImage *)ciImage andSize:(CGFloat)size{  
  10.     CGRect extent = CGRectIntegral(ciImage.extent);  
  11.     CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));  
  12.       
  13.     // 创建bitmap;  
  14.     size_t width = CGRectGetWidth(extent) * scale;  
  15.     size_t height = CGRectGetHeight(extent) * scale;  
  16.     CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();  
  17.     CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 80, cs, (CGBitmapInfo)kCGImageAlphaNone);  
  18.     CIContext *context = [CIContext contextWithOptions:nil];  
  19.     CGImageRef bitmapImage = [context createCGImage:ciImage fromRect:extent];  
  20.     CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);  
  21.     CGContextScaleCTM(bitmapRef, scale, scale);  
  22.     CGContextDrawImage(bitmapRef, extent, bitmapImage);  
  23.       
  24.     // 保存bitmap到图片  
  25.     CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);  
  26.     CGContextRelease(bitmapRef);  
  27.     CGImageRelease(bitmapImage);  
  28.       
  29.     return [UIImage imageWithCGImage:scaledImage];  
  30. }  
[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. self.imageView2.image = [RadiusImage changeImageSizeWithCIImage:ciImage andSize:180];  
这个imageView2显示的图片就是最清晰的那张二维码图片。


其实可以把上面两个方法合并在一起,我们只需要传递一个URL和二维码显示的控件就可以一行代码生成我们自己的二维码控件了。

阅读更多
换一批

没有更多推荐了,返回首页