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

苹果原生二维码实现

作者: 墨_辰 | 来源:发表于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