.h文件

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Public : NSObject

/*创建二维码图片
 *message:二维码所带信息
 *codeWidth:二维码宽度(二维码默认为正方形,所以仅需提供宽度)
 *red-green-blue:二维码颜色
 *insertImage:插入图像图片,若为nil则不插入头像仅返回二维码
 *roundRadius:插入头像圆角大小
 */
+ (UIImage *)creatQRCodeImageWithMessageStr:(NSString *)message
                                  codeWidth: (CGFloat)codeWidth
                                        red: (NSUInteger)red
                                      green: (NSUInteger)green
                                       blue: (NSUInteger)blue
                                insertImage: (UIImage *)insertImage
                                roundRadius: (CGFloat)roundRadius;

@end

 .m文件

#import "Public.h"

#define appName @"appName"
#define MaxCodeWidth 160
#define MixCodeMargin 80
#define centerImageWhiteBorderWidth 2

@implementation Public


/*创建二维码图片
 *message:二维码所带信息
 *codeWidth:二维码宽度(二维码默认为正方形,所以仅需提供宽度)
 *red-green-blue:二维码颜色
 *insertImage:插入图像图片,若为nil则不插入头像仅返回二维码
 *roundRadius:插入头像圆角大小
 */
+ (UIImage *)creatQRCodeImageWithMessageStr:(NSString *)message
                                  codeWidth: (CGFloat)codeWidth
                                        red: (NSUInteger)red
                                      green: (NSUInteger)green
                                       blue: (NSUInteger)blue
                                insertImage: (UIImage *)insertImage
                                roundRadius: (CGFloat)roundRadius{
    
    //【1】信息为空则返回nil
    if ((!message) || (message.length == 0)) {
        return nil;
    }
    
    //【2】验证二维码尺寸的合理大小
    codeWidth = [self validateCodeWidth:codeWidth];
    
    
    //【3】使用存储信息生成二维码
    // 1.创建过滤器,这里的@"CIQRCodeGenerator"是固定的
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    // 2.恢复默认设置
    [filter setDefaults];
    // 3. 给过滤器添加数据
    NSString *dataString = [NSString stringWithFormat:@"%@--%@",appName,message];
    NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    // 注意,这里的value必须是NSData类型
    [filter setValue:data forKeyPath:@"inputMessage"];
    // 4. 生成二维码
    CIImage *outputImage = [filter outputImage];
    
    
    //【4】返回
    UIImage * progressImage = [self excludeFuzzyImageFromCIImage:outputImage size:codeWidth];//进行清晰化处理后的二维码
    UIImage * effectiveImage = [self imageFillBlackColorAndTransparent: progressImage red:red green:green blue:blue];  //进行颜色渲染后的二维码
    
    if (insertImage) {
        return [self imageInsertedImage:effectiveImage insertImage:insertImage radius:roundRadius];//返回插入头像之后的二维码
    }
    return effectiveImage;
    
}

/* 验证二维码尺寸合法性*/
+ (CGFloat)validateCodeWidth:(CGFloat)codeWidth {
    codeWidth = MAX(MaxCodeWidth, codeWidth);
    codeWidth = MIN(CGRectGetWidth([UIScreen mainScreen].bounds) - MixCodeMargin, codeWidth);
    return codeWidth;
    
}

/* 对图像进行清晰化处理*/
+ (UIImage *)excludeFuzzyImageFromCIImage: (CIImage *)image
                                     size: (CGFloat)size {
    
    CGRect extent = CGRectIntegral(image.extent);
    CGFloat scale = MIN(size / CGRectGetWidth(extent), size / CGRectGetHeight(extent));
    size_t width = CGRectGetWidth(extent) * scale;
    size_t height = CGRectGetHeight(extent) * scale;
    
    //创建灰度色调空间
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpace, (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);
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    CGColorSpaceRelease(colorSpace);
    return [UIImage imageWithCGImage: scaledImage];
    
}

/* 对生成二维码图像进行颜色填充*/
+ (UIImage *)imageFillBlackColorAndTransparent:(UIImage *)image
                                           red:(NSUInteger)red
                                         green:(NSUInteger)green
                                          blue:(NSUInteger)blue {
    
    const int imageWidth = image.size.width;
    const int imageHeight = image.size.height;
    
    size_t bytesPerRow = imageWidth * 4;
    uint32_t * rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    
    CGContextDrawImage(context, (CGRect){(CGPointZero), (image.size)}, image.CGImage);
    
    //遍历像素
    int pixelNumber = imageHeight * imageWidth;
    
    [self fillWhiteToTransparentOnPixel:rgbImageBuf pixelNum:pixelNumber red:red green:green blue:blue];
    
    CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow, ProviderReleaseData);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider, NULL, true, kCGRenderingIntentDefault);
    
    UIImage * resultImage = [UIImage imageWithCGImage: imageRef];
    CGImageRelease(imageRef);
    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    return resultImage;
    
}

void ProviderReleaseData(void * info, const void * data, size_t size) {
    
    free((void *)data);
    
}

/* 遍历所有像素点进行颜色替换*/
+ (void)fillWhiteToTransparentOnPixel:(uint32_t *)rgbImageBuf
                             pixelNum:(int)pixelNum
                                  red:(NSUInteger)red
                                green:(NSUInteger)green
                                 blue:(NSUInteger)blue {
    
    uint32_t * pCurPtr = rgbImageBuf;
    
    for (int i = 0; i < pixelNum; i++, pCurPtr++) {
        if ((*pCurPtr & 0xffffff00) < 0xd0d0d000) {
            uint8_t * ptr = (uint8_t *)pCurPtr;
            ptr[3] = red;
            ptr[2] = green;
            ptr[1] = blue;
            
        } else {
            //将白色变成透明色
            uint8_t * ptr = (uint8_t *)pCurPtr;
            ptr[0] = 0;
            
        }
        
    }
    
}



/* 在二维码原图中心位置插入圆角图像*/
+ (UIImage *)imageInsertedImage:(UIImage *)originImage
                    insertImage:(UIImage *)insertImage
                         radius:(CGFloat)radius {
    
    insertImage = [self imageOfRoundRectWithImage:insertImage size:insertImage.size radius:radius];
    
    UIImage * whiteBG = [UIImage imageNamed:@"timeWhiteBg"];
    whiteBG = [self imageOfRoundRectWithImage:whiteBG size:whiteBG.size radius:radius];
    
    
    CGSize brinkSize = CGSizeMake(originImage.size.width / 4, originImage.size.height / 4);
    CGFloat brinkX = (originImage.size.width - brinkSize.width) * 0.5;
    CGFloat brinkY = (originImage.size.height - brinkSize.height) * 0.5;
    CGSize imageSize = CGSizeMake(brinkSize.width - 2 * centerImageWhiteBorderWidth, brinkSize.height - 2 * centerImageWhiteBorderWidth);
    
    CGFloat imageX = brinkX + centerImageWhiteBorderWidth;
    CGFloat imageY = brinkY + centerImageWhiteBorderWidth;
    
    UIGraphicsBeginImageContext(originImage.size);
    [originImage drawInRect: (CGRect){ 0, 0, (originImage.size) }];
    [whiteBG drawInRect: (CGRect){ brinkX, brinkY, (brinkSize) }];
    [insertImage drawInRect: (CGRect){ imageX, imageY, (imageSize) }];
    
    UIImage * resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return resultImage;
    
}


/* 绘制圆角*/
+ (UIImage *)imageOfRoundRectWithImage:(UIImage *)image
                                  size:(CGSize)size
                                radius:(CGFloat)radius {
    if (!image) {
        return nil;
    }
    
    const CGFloat width = size.width;
    const CGFloat height = size.height;
    
    radius = MAX(5.f, radius);
    radius = MIN(10.f, radius);
    
    UIImage * img = image;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedFirst);
    CGRect rect = CGRectMake(0, 0, width, height);
    
    //绘制圆角
    CGContextBeginPath(context);
    CGContextDrawImage(context, rect, img.CGImage);
    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    img = [UIImage imageWithCGImage: imageMasked];
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageMasked);
    
    return img;
    
}


@end

 

posted on 2017-04-14 15:30  fatal-奚山遇白  阅读(218)  评论(0)    收藏  举报