美文网首页程序员
苹果原生二维码实现

苹果原生二维码实现

作者: 墨_辰 | 来源:发表于2018-05-16 16:01 被阅读0次

前几天不是要求做一个二维码扫描嘛,而且要求用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

相关文章

网友评论

    本文标题:苹果原生二维码实现

    本文链接:https://www.haomeiwen.com/subject/ytopdftx.html