生成二维码就不是AVFoundation架构了,使用的是CoreImage。之前在航歌上面看见一篇使用Swift生成二维码的文章。看了之后,我就想想,Swift可以使用原生的,那么OC可不可以呢?经过测试是可以的,而且可以生成带logo的。使用起来也很简单。
首先看看两种图片:
左右两张图,都是同一个二维码,可以扫扫,有惊喜的。
左边的一张看起来模糊,右边的看起来清晰多了,这又是为什么呢?下面就会有解答的。
怎么生成二维码:
- /**
- * 根据字符串生成二维码 CIImage 对象
- *
- * @param urlString 需要生成二维码的字符串
- *
- * @return 生成的二维码
- */
- + (CIImage *)creatQRcodeWithUrlstring:(NSString *)urlString{
- // 1.实例化二维码滤镜
- CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
- // 2.恢复滤镜的默认属性 (因为滤镜有可能保存上一次的属性)
- [filter setDefaults];
- // 3.将字符串转换成NSdata
- NSData *data = [urlString dataUsingEncoding:NSUTF8StringEncoding];
- // 4.通过KVO设置滤镜, 传入data, 将来滤镜就知道要通过传入的数据生成二维码
- [filter setValue:data forKey:@"inputMessage"];
- // 5.生成二维码
- CIImage *outputImage = [filter outputImage];
- return outputImage;
- }
- CIImage *ciImage = [RadiusImage creatQRcodeWithUrlstring:@"http://blog.csdn.net/zhuming3834"];
- UIImage *im = [UIImage imageWithCIImage:ciImage];
- self.imageView.image = im;
为什么会模糊呢?
我们可以打印一下生成的图片的size:
- NSLog(@"im.size.height = %f,im.size.width = %f",im.size.height,im.size.width);
- // im.size.height = 31.000000,im.size.width = 31.000000
怎么解决这个问题呢?
写在这里的时候,想起了一个方法:
- im = [im stretchableImageWithLeftCapWidth:im.size.height/2 topCapHeight:im.size.width/2];
- self.imageView2.image = im;
这是什么啊?上面的方法确实是拉伸图片,但是它使用图片的中心点开始拉伸,图片里面的元素也被拉伸了(向四周扩展了,而被挤到了一起)。很显然这个方法不能使用。那么有没有更好的方法呢?答案是有的。
- /**
- * 改变图片大小 (正方形图片)
- *
- * @param ciImage 需要改变大小的CIImage 对象的图片
- * @param size 图片大小 (正方形图片 只需要一个数)
- *
- * @return 生成的目标图片
- */
- + (UIImage *)changeImageSizeWithCIImage:(CIImage *)ciImage andSize:(CGFloat)size{
- CGRect extent = CGRectIntegral(ciImage.extent);
- CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
- // 创建bitmap;
- size_t width = CGRectGetWidth(extent) * scale;
- size_t height = CGRectGetHeight(extent) * scale;
- CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
- CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
- CIContext *context = [CIContext contextWithOptions:nil];
- CGImageRef bitmapImage = [context createCGImage:ciImage fromRect:extent];
- CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
- CGContextScaleCTM(bitmapRef, scale, scale);
- CGContextDrawImage(bitmapRef, extent, bitmapImage);
- // 保存bitmap到图片
- CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
- CGContextRelease(bitmapRef);
- CGImageRelease(bitmapImage);
- return [UIImage imageWithCGImage:scaledImage];
- }
- self.imageView2.image = [RadiusImage changeImageSizeWithCIImage:ciImage andSize:180];
其实可以把上面两个方法合并在一起,我们只需要传递一个URL和二维码显示的控件就可以一行代码生成我们自己的二维码控件了。