【iOS】CoreImage原生二维码生成(一)

在几个月前写过一篇关于二维码读取的博客,【iOS】AVFoundation架构下的原生二维码和条形码扫描。今天记录下原生的二维码的生成(今天先写一部分,生成不带logo的二维码)。

生成二维码就不是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对象,在显示的时候还需要先转换为UIImage对象。

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
生成的二维码图片的大小是31x31,而我们的控件imageView的大小是180x180。原来是图片被 拉伸了导致的模糊。

怎么解决这个问题呢?

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

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];
这个imageView2显示的图片就是最清晰的那张二维码图片。


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

下一篇文章中,我就会这个干。这里就不放上代码的下载地址了,在公司不能上传东西啊。( ⊙ o ⊙ )啊!


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
如果不想使用CoreImage框架,也可以使用ZBarSDK来获取图片二维码的定位。 1. 导入ZBarSDK: 在项目中导入ZBarSDK,并在需要使用的文件中引入头文件: ``` #import "ZBarSDK.h" ``` 2. 加载图片: ``` UIImage *image = [UIImage imageNamed:@"image.png"]; CGImageRef imageRef = image.CGImage; ``` 3. 创建ZBarImageScanner并设置识别类型: ``` ZBarImageScanner *scanner = [[ZBarImageScanner alloc] init]; [scanner setSymbology: ZBAR_QRCODE config: ZBAR_CFG_ENABLE to: 1]; ``` 4. 将图片转换为ZBarImage对象: ``` ZBarImage *zbarImage = [[ZBarImage alloc] initWithCGImage:imageRef]; ``` 5. 扫描二维码: ``` [scanner scanImage:zbarImage]; ``` 6. 遍历扫描结果,获取二维码定位: ``` for (ZBarSymbol *symbol in scanner.results) { NSArray *corners = symbol.bounds; // 获取定位四个角的坐标 // 在图像上绘制定位 UIGraphicsBeginImageContext(imageSize); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor); CGContextSetLineWidth(context, 2.0); CGContextMoveToPoint(context, corners[0].x, corners[0].y); CGContextAddLineToPoint(context, corners[1].x, corners[1].y); CGContextAddLineToPoint(context, corners[2].x, corners[2].y); CGContextAddLineToPoint(context, corners[3].x, corners[3].y); CGContextAddLineToPoint(context, corners[0].x, corners[0].y); CGContextStrokePath(context); UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } ``` 这样就可以在原图上绘制出二维码的定位了。需要注意的是,ZBarSDK是第三方框架,需要先在官网注册并获取授权才能使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值