Date
Sep. 8th, 2024
 
2024年 8月 6日

Post: iOS : 二维码生成

iOS : 二维码生成

Published 12:02 Feb 14, 2015.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

最近发过几个关于二维码的内容( 相机扫描二维码识别图片二维码,趁热打铁,再来一篇二维码生成的博文吧。

看过前面文章的小伙伴肯定猜到了,这里还是使用 CI 系列。是的,在 iOS 7 之后我们可以使用苹果提供的 CIFilter 来实现二维码的生成。

+ (CIImage *)imageFromString:(NSString *)string {
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    [filter setValue:@"H" forKey:@"inputCorrectionLevel"];
    [filter setValue:[string dataUsingEncoding:NSUTF8StringEncoding] forKey:@"inputMessage"];
    return filter.outputImage;
}

这里要特别说明一下 inputCorrectionLevel ,也就是纠错等级,允许的值有 L / M / Q / H 四种,依次对应7%,15%,25%,30%的容错度,生成器会通过重复表示部分信息,也就是信息冗余,来提高其容错度,这样在二维码被遮挡或缺失一部分时,也有机会成功被解析。

通过上面的代码,成功生成一张二维码图像的 CIImage 实例,那么问题来了:

  • 我们最常用的是 UIImage 实例

  • 图像模糊

  • 尺寸不易控制

为了解决这些问题,我们需要添加新的步骤,这里我为 UIImage 添加了一个分类,使用绘制位图的方式来产生一个指定尺寸的 UIImage 实例:

@implementation UIImage (CIImage)
+ (UIImage *)imageWithCIImage:(CIImage *)image borderLength:(CGFloat)borderLength {
    // 原图尺寸
    CGRect extent = CGRectIntegral(image.extent);
    // 缩放比
    CGFloat scale = MIN(borderLength/CGRectGetWidth(extent), borderLength/CGRectGetHeight(extent));
    size_t width = CGRectGetWidth(extent) * scale;
    size_t height = CGRectGetHeight(extent) * scale;
    // 色域
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
    // 上下文
    CIContext *context = [CIContext contextWithOptions:nil];
    // 创建位图
    CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
    // 位图上下文
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    // 属性设定与绘制
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);
    // 产生 CGImage
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    // 释放
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    // 产生并返回 UIImage
    return [UIImage imageWithCGImage:scaledImage];
}
@end

好了,现在我们可以得到一个尺寸合适、足够清晰的二维码图片了。

如果你对生成的图片还有其他需求,例如需要更换二维码的颜色等,你可以继续改造上面的方法,这里不再赘述。

Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
程序猿、设计师、奇怪的博主。
苹果死忠、热爱色彩斑斓的世界。
如有意向请随时 与我联系