前几天不是要求做一个二维码扫描嘛,而且要求用zxing库来搞,最近又要求增加一个二维码生成的功能。虽然也可以用ZXing来实现,而且很简单,但是我个人偏向于使用苹果的原生库,这次的没啥要求,所以就拿原生库来做咯,就当熟悉一下原生库吗,感觉总是用第三方库真的不好玩。
需求:根据分享的网址生成一个二维码,并且在二维码的中间添加logo。
首先是QRCode.h文件,定义了三个方法,第一个是生成普通二维码,第二个是生成带logo的二维码,第三个是生成有背景颜色的二维码:
#import <Foundation/Foundation.h>
#import <CoreImage/CoreImage.h>
#import <UIKit/UIKit.h>
@interface QRCode : NSObject
/**
* 根据CIImage生成指定大小的UIImage
* @param image CIImage
* @param size 图片宽度
* @return 生成高清的UIImage
*/
+ (UIImage *)creatQRCode:(NSString *)data withSize:(CGFloat)size;
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param scale logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同,一般取0.25)
*/
+ (UIImage *)createQRCodeWithLogo:(NSString *)data logoName:(NSString *)logoImageName Scale:(CGFloat)scale;
/**
* 生成一张彩色的二维码
*
* @param data 传入你要生成二维码的数据
* @param backgroundColor 背景色
* @param mainColor 主颜色
*/
+ (UIImage *)createQRCodeWithColor:(NSString *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor ;
接下来是实现方法,QRcode.m文件,注释挺细的,就不多逼逼了:
#import "QRCode.h"
@implementation QRCode
+ (UIImage *)creatQRCode:(NSString *)data withSize:(CGFloat)size{
CIImage *image = [self creatQRcodeWithUrlstring:data];
return [self creatNonInterpolatedUIImageFormCIImage:image withSize:size];
}
+ (UIImage *)createQRCodeWithLogo:(NSString *)data logoName:(NSString *)logoName Scale:(CGFloat)scale{
CIImage *image = [self creatQRcodeWithUrlstring:data];
return [self generateWithLogoQRCodeData:image logoImageName:logoName logoScaleToSuperView:scale];
}
+ (UIImage *)createQRCodeWithColor:(NSString *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor{
CIImage *image = [self creatQRcodeWithUrlstring:data];
return [self generateWithColorQRCodeData:image backgroundColor:backgroundColor mainColor:mainColor];
}
/**
* 根据字符串生成二维码 CIImage 对象
* @param urlString 需要生成二维码的字符串
*/
+ (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;
}
+ (UIImage *)creatNonInterpolatedUIImageFormCIImage:(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];
//水印图
// UIImage *waterimage = [UIImage imageNamed:@"icon"];
// [waterimage drawInRect:CGRectMake(0,0,10,10)];
// UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
// UIGraphicsEndImageContext();
// return newPic;
}
+ (UIImage *)generateWithLogoQRCodeData:(CIImage *)baseImage logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView {
// 图片小于(27,27),我们需要放大
baseImage = [baseImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
// 将CIImage类型转成UIImage类型
UIImage *start_image = [UIImage imageWithCIImage:baseImage];
// - - - - - - - - - - - - - - - - 添加中间小图标 - - - - - - - - - - - - - - - -
// 开启绘图, 获取图形上下文 (上下文的大小, 就是二维码的大小)
UIGraphicsBeginImageContext(start_image.size);
// 把二维码图片画上去 (这里是以图形上下文, 左上角为(0,0)点
[start_image drawInRect:CGRectMake(0, 0, start_image.size.width, start_image.size.height)];
// 再把logo图片画上去
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)];
//获取当前画得的这张图片
UIImage *final_image = UIGraphicsGetImageFromCurrentImageContext();
//关闭图形上下文
UIGraphicsEndImageContext();
return final_image;
}
+ (UIImage *)generateWithColorQRCodeData:(CIImage *)baseImage backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor {
// 图片小于(27,27),我们需要放大
baseImage = [baseImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
// 创建彩色过滤器(彩色的用的不多)
CIFilter * color_filter = [CIFilter filterWithName:@"CIFalseColor"];
// 设置默认值
[color_filter setDefaults];
// KVC 给私有属性赋值
[color_filter setValue:baseImage forKey:@"inputImage"];
// 需要使用 CIColor
[color_filter setValue:backgroundColor forKey:@"inputColor0"];
[color_filter setValue:mainColor forKey:@"inputColor1"];
//设置输出
CIImage *colorImage = [color_filter outputImage];
return [UIImage imageWithCIImage:colorImage];
}
@end
这样就搞定了,用原生库生成二维码还是比较简单的。
文章参考了袁俊亮的博客(链接附上),而且他的文章中也有扫描的部分,需要的可以看一下:
(https://www.jianshu.com/p/b8bf300e9a56)
另外还参考了一个叫做SGQRCode的第三方库,挺好用的,功能也很全,不想自己写的可以直接集成到自己的项目中,集成方法如下:
1、CocoaPods 导入 pod 'SGQRCode', '~> 2.2.0’;
2、下载、拖拽 “SGQRCode” 文件夹到工程中;
GitHub链接附上:
https://github.com/kingsic/SGQRCode
网友评论