iOS开发如何设置CIFilter生成的二维码样式 实现高密度二维码效果
iOS 生成高密度二维码配置调整方案
当前实现代码
// 1. 初始化二维码滤镜 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; // 恢复滤镜默认配置 [filter setDefaults]; // 2. 配置二维码内容 NSString *string = @"http://192.168.0.116/1"; NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; // 传入待生成内容 [filter setValue:data forKeyPath:@"inputMessage"]; // 3. 生成初始二维码图像 CIImage *image = [filter outputImage]; // 4. 拉伸适配ImageView尺寸 CGFloat scaleX = self.imageView.frame.size.width / image.extent.size.width; CGFloat scaleY = self.imageView.frame.size.height / image.extent.size.height; image = [image imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)]; self.imageView.image = [UIImage imageWithCIImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
当前生成效果

目标效果

调整方法
你当前代码未设置二维码纠错等级,默认使用中等纠错等级生成二维码,相同内容下模块数量少、密度低,同时直接拉伸原始CIImage容易出现边缘模糊,调整以下两点即可实现目标效果:
- 给
CIQRCodeGenerator滤镜设置inputCorrectionLevel参数值为H(最高纠错等级,支持30%内容容错),相同输入内容下会生成更多二维码点阵模块,视觉密度更高 - 替换原有仿射变换拉伸逻辑,使用位图上下文绘制的方式做无插值缩放,保证高密度点阵的边缘清晰锐利,不会出现模糊发虚的问题
调整后可直接使用的代码
// 1. 初始化二维码滤镜 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; [filter setDefaults]; // 2. 配置生成参数 NSString *string = @"http://192.168.0.116/1"; NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; [filter setValue:data forKeyPath:@"inputMessage"]; // 关键配置:设置最高纠错等级,提升点阵密度 [filter setValue:@"H" forKey:@"inputCorrectionLevel"]; // 3. 生成初始二维码CIImage CIImage *outputImage = [filter outputImage]; // 4. 高清无模糊缩放适配目标尺寸 CGSize targetSize = self.imageView.bounds.size; CGRect extent = CGRectIntegral(outputImage.extent); CGFloat scale = MIN(targetSize.width/CGRectGetWidth(extent), targetSize.height/CGRectGetHeight(extent)); 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:outputImage fromRect:extent]; // 关闭插值,保证点阵边缘锐利 CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone); CGContextScaleCTM(bitmapRef, scale, scale); CGContextDrawImage(bitmapRef, extent, bitmapImage); // 导出最终UIImage并赋值 CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef); self.imageView.image = [UIImage imageWithCGImage:scaledImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]; // 释放资源 CGContextRelease(bitmapRef); CGImageRelease(bitmapImage); CGImageRelease(scaledImage); CGColorSpaceRelease(cs);
补充提示:如果需要更高的点阵密度,可以在不影响业务识别的前提下,在二维码内容末尾追加无意义的填充字符,输入内容越长生成的二维码点阵模块越多、密度越高,注意不要超过对应纠错等级支持的最大内容长度即可。
内容的提问来源于stack exchange,提问作者liangdapang
相关产品推荐
相关产品推荐

