最近项目需要,后台返回byte数据,直接转化为二维码,以前都是字符串格式,总结出一个类,完美完成三种二维码:带 logo、不带logo、彩色二维码等
一、建一个类
.h文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface JCQRCodeTool : NSObject
/**
* 生成一张普通的二维码
*
* @param data 传入你要生成二维码的数据
* @param imageViewWidth 图片的宽度
*/
+ (UIImage *)generateWithDefaultQRCodeData:(NSData *)data imageViewWidth:(CGFloat)imageViewWidth;
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param logoScaleToSuperView logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同)
*/
+ (UIImage *)generateWithLogoQRCodeData:(NSData *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView;
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param logoScaleToSuperView logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同)
*/
+ (UIImage *)generateWithLogoQRCodeString:(NSString *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView;
/**
* 生成一张彩色的二维码
*
* @param data 传入你要生成二维码的数据
* @param backgroundColor 背景色
* @param mainColor 主颜色
*/
+ (UIImage *)generateWithColorQRCodeData:(NSData *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor;
@end
.m文件
#import "JCQRCodeTool.h"
@implementation JCQRCodeTool
/**
* 生成一张普通的二维码
*
* @param data 传入你要生成二维码的数据
* @param imageViewWidth 图片的宽度
*/
+ (UIImage *)generateWithDefaultQRCodeData:(NSData *)data imageViewWidth:(CGFloat)imageViewWidth {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// // 2、设置数据
// NSString *info = data;
// // 将字符串转换成
// NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding];
// 通过KVC设置滤镜inputMessage数据
[filter setValue:data forKeyPath:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
return [self createNonInterpolatedUIImageFormCIImage:outputImage withSize:imageViewWidth];
}
/** 根据CIImage生成指定大小的UIImage */
+ (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 1.创建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:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 2.保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param logoScaleToSuperView logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同)
*/
+ (UIImage *)generateWithLogoQRCodeData:(NSData *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
// NSString *string_data = @"123";
// // 将字符串转换成 NSdata (虽然二维码本质上是字符串, 但是这里需要转换, 不转换就崩溃)
// NSData *qrImageData = [string_data dataUsingEncoding:NSUTF8StringEncoding];
// // 设置过滤器的输入值, KVC赋值
// [filter setValue:qrImageData forKey:@"inputMessage"];
// 设置过滤器的输入值, KVC赋值
[filter setValue:data forKey:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
// 图片小于(27,27),我们需要放大
outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
// 4、将CIImage类型转成UIImage类型
UIImage *start_image = [UIImage imageWithCIImage:outputImage];
// - - - - - - - - - - - - - - - - 添加中间小图标 - - - - - - - - - - - - - - - -
// 5、开启绘图, 获取图形上下文 (上下文的大小, 就是二维码的大小)
UIGraphicsBeginImageContext(start_image.size);
// 把二维码图片画上去 (这里是以图形上下文, 左上角为(0,0)点
[start_image drawInRect:CGRectMake(0, 0, start_image.size.width, start_image.size.height)];
// 再把小图片画上去
NSString *icon_imageName = logoImageName;
UIImage *icon_image = [UIImage imageNamed:icon_imageName];
CGFloat icon_imageW = start_image.size.width * logoScaleToSuperView;
CGFloat icon_imageH = start_image.size.height * logoScaleToSuperView;
CGFloat icon_imageX = (start_image.size.width - icon_imageW) * 0.5;
CGFloat icon_imageY = (start_image.size.height - icon_imageH) * 0.5;
[icon_image drawInRect:CGRectMake(icon_imageX, icon_imageY, icon_imageW, icon_imageH)];
// 6、获取当前画得的这张图片
UIImage *final_image = UIGraphicsGetImageFromCurrentImageContext();
// 7、关闭图形上下文
UIGraphicsEndImageContext();
return final_image;
}
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param logoScaleToSuperView logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同)
*/
+ (UIImage *)generateWithLogoQRCodeString:(NSString *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
NSString *string_data = data;
// 将字符串转换成 NSdata (虽然二维码本质上是字符串, 但是这里需要转换, 不转换就崩溃)
NSData *qrImageData = [string_data dataUsingEncoding:NSUTF8StringEncoding];
// 设置过滤器的输入值, KVC赋值
[filter setValue:qrImageData forKey:@"inputMessage"];
// 设置过滤器的输入值, KVC赋值
// [filter setValue:data forKey:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
// 图片小于(27,27),我们需要放大
outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
// 4、将CIImage类型转成UIImage类型
UIImage *start_image = [UIImage imageWithCIImage:outputImage];
// - - - - - - - - - - - - - - - - 添加中间小图标 - - - - - - - - - - - - - - - -
// 5、开启绘图, 获取图形上下文 (上下文的大小, 就是二维码的大小)
UIGraphicsBeginImageContext(start_image.size);
// 把二维码图片画上去 (这里是以图形上下文, 左上角为(0,0)点
[start_image drawInRect:CGRectMake(0, 0, start_image.size.width, start_image.size.height)];
// 再把小图片画上去
NSString *icon_imageName = logoImageName;
UIImage *icon_image = [UIImage imageNamed:icon_imageName];
CGFloat icon_imageW = start_image.size.width * logoScaleToSuperView;
CGFloat icon_imageH = start_image.size.height * logoScaleToSuperView;
CGFloat icon_imageX = (start_image.size.width - icon_imageW) * 0.5;
CGFloat icon_imageY = (start_image.size.height - icon_imageH) * 0.5;
[icon_image drawInRect:CGRectMake(icon_imageX, icon_imageY, icon_imageW, icon_imageH)];
// 6、获取当前画得的这张图片
UIImage *final_image = UIGraphicsGetImageFromCurrentImageContext();
// 7、关闭图形上下文
UIGraphicsEndImageContext();
return final_image;
}
/**
* 生成一张彩色的二维码
*
* @param data 传入你要生成二维码的数据
* @param backgroundColor 背景色
* @param mainColor 主颜色
*/
+ (UIImage *)generateWithColorQRCodeData:(NSData *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
// NSString *string_data = data;
// // 将字符串转换成 NSdata (虽然二维码本质上是字符串, 但是这里需要转换, 不转换就崩溃)
// NSData *qrImageData = [string_data dataUsingEncoding:NSUTF8StringEncoding];
// 设置过滤器的输入值, KVC赋值
[filter setValue:data forKey:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
// 图片小于(27,27),我们需要放大
outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
// 4、创建彩色过滤器(彩色的用的不多)
CIFilter * color_filter = [CIFilter filterWithName:@"CIFalseColor"];
// 设置默认值
[color_filter setDefaults];
// 5、KVC 给私有属性赋值
[color_filter setValue:outputImage forKey:@"inputImage"];
// 6、需要使用 CIColor
[color_filter setValue:backgroundColor forKey:@"inputColor0"];
[color_filter setValue:mainColor forKey:@"inputColor1"];
// 7、设置输出
CIImage *colorImage = [color_filter outputImage];
return [UIImage imageWithCIImage:colorImage];
}
二、使用方法
NSData *codeData = [GTMBase64 decodeString:QRCode];
_codeIV.image = [JCQRCodeTool generateWithLogoQRCodeData:codeData logoImageName:@"rz_logo_icon" logoScaleToSuperView:0.2];
下载地址:下载