iOS 生成二维码带图片

本文介绍了一个Objective-C类库,用于创建包含图标并可调整颜色及尺寸的二维码。提供了详细的代码实现,包括生成二维码、调整二维码大小、改变颜色、添加图标等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#import <Foundation/Foundation.h>

 #import <UIKit/UIKit.h>

#import <CoreImage/CoreImage.h>



@interface KMQRCode : NSObject

+ (CIImage *)createQRCodeImage:(NSString *)source;

+ (UIImage *)resizeQRCodeImage:(CIImage *)image withSize:(CGFloat)size;

+ (UIImage *)specialColorImage:(UIImage*)image withRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue;

+ (UIImage *)addIconToQRCodeImage:(UIImage *)image withIcon:(UIImage *)icon withIconSize:(CGSize)iconSize;

+ (UIImage *)addIconToQRCodeImage:(UIImage *)image withIcon:(UIImage *)icon withScale:(CGFloat)scale;

@end



#import "KMQRCode.h"


@implementation KMQRCode


#pragma mark - Private Methods

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

    free((void*)data);

}


#pragma mark - Public Methods

+ (CIImage *)createQRCodeImage:(NSString *)source {

    NSData *data = [source dataUsingEncoding:NSUTF8StringEncoding];

    

    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];

    [filter setValue:data forKey:@"inputMessage"];

    [filter setValue:@"Q" forKey:@"inputCorrectionLevel"]; //设置纠错等级越高;即识别越容易,值可设置为L(Low) |  M(Medium) | Q | H(High)

    return filter.outputImage;

}


+ (UIImage *)resizeQRCodeImage:(CIImage *)image withSize:(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 colorSpaceRef = CGColorSpaceCreateDeviceGray();

    

    CGContextRef contextRef = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpaceRef, (CGBitmapInfo)kCGImageAlphaNone);

    CIContext *context = [CIContext contextWithOptions:nil];

    CGImageRef imageRef = [context createCGImage:image fromRect:extent];

    CGContextSetInterpolationQuality(contextRef, kCGInterpolationNone);

    CGContextScaleCTM(contextRef, scale, scale);

    CGContextDrawImage(contextRef, extent, imageRef);

    

    CGImageRef imageRefResized = CGBitmapContextCreateImage(contextRef);

    

    //Release

    CGContextRelease(contextRef);

    CGImageRelease(imageRef);

    return [UIImage imageWithCGImage:imageRefResized];

}


+ (UIImage *)specialColorImage:(UIImage*)image withRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)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);

    

    //Create context

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    CGContextRef contextRef = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpaceRef, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);

    CGContextDrawImage(contextRef, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);

    

    //Traverse pixe

    int pixelNum = imageWidth * imageHeight;

    uint32_t* pCurPtr = rgbImageBuf;

    for (int i = 0; i < pixelNum; i++, pCurPtr++){

        if ((*pCurPtr & 0xFFFFFF00) < 0x99999900){

            //Change color

            uint8_t* ptr = (uint8_t*)pCurPtr;

            ptr[3] = red; //0~255

            ptr[2] = green;

            ptr[1] = blue;

        }else{

            uint8_t* ptr = (uint8_t*)pCurPtr;

            ptr[0] = 0;

        }

    }

    

    //Convert to image

    CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);

    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpaceRef,

                                        kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProviderRef,

                                        NULL, true, kCGRenderingIntentDefault);

    CGDataProviderRelease(dataProviderRef);

    UIImage* img = [UIImage imageWithCGImage:imageRef];

    

    //Release

    CGImageRelease(imageRef);

    CGContextRelease(contextRef);

    CGColorSpaceRelease(colorSpaceRef);

    return img;

}


+(UIImage *)addIconToQRCodeImage:(UIImage *)image withIcon:(UIImage *)icon withIconSize:(CGSize)iconSize {

    UIGraphicsBeginImageContext(image.size);

    //通过两张图片进行位置和大小的绘制,实现两张图片的合并;其实此原理做法也可以用于多张图片的合并

    CGFloat widthOfImage = image.size.width;

    CGFloat heightOfImage = image.size.height;

    CGFloat widthOfIcon = iconSize.width;

    CGFloat heightOfIcon = iconSize.height;

    

    [image drawInRect:CGRectMake(0, 0, widthOfImage, heightOfImage)];

    [icon drawInRect:CGRectMake((widthOfImage-widthOfIcon)/2, (heightOfImage-heightOfIcon)/2,

                                widthOfIcon, heightOfIcon)];

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;

}


+(UIImage *)addIconToQRCodeImage:(UIImage *)image withIcon:(UIImage *)icon withScale:(CGFloat)scale {

    UIGraphicsBeginImageContext(image.size);

    

    //通过两张图片进行位置和大小的绘制,实现两张图片的合并;其实此原理做法也可以用于多张图片的合并

    CGFloat widthOfImage = image.size.width;

    CGFloat heightOfImage = image.size.height;

    CGFloat widthOfIcon = widthOfImage/scale;

    CGFloat heightOfIcon = heightOfImage/scale;

    

    [image drawInRect:CGRectMake(0, 0, widthOfImage, heightOfImage)];

    [icon drawInRect:CGRectMake((widthOfImage-widthOfIcon)/2, (heightOfImage-heightOfIcon)/2,

                                widthOfIcon, heightOfIcon)];

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

    

    UIGraphicsEndImageContext();

    return img;

}


@end


#import <UIKit/UIKit.h>


@interface UIImage (RoundedRectImage)

+ (UIImage *)createRoundedRectImage:(UIImage *)image withSize:(CGSize)size withRadius:(NSInteger)radius;

@end


#import "UIImage+RoundedRectImage.h"


@implementation UIImage (RoundedRectImage)


#pragma mark - Private Methods

static void addRoundedRectToPath(CGContextRef contextRef, CGRect rect, float widthOfRadius, float heightOfRadius) {

    float fw, fh;

    if (widthOfRadius == 0 || heightOfRadius == 0)

    {

        CGContextAddRect(contextRef, rect);

        return;

    }

    

    CGContextSaveGState(contextRef);

    CGContextTranslateCTM(contextRef, CGRectGetMinX(rect), CGRectGetMinY(rect));

    CGContextScaleCTM(contextRef, widthOfRadius, heightOfRadius);

    fw = CGRectGetWidth(rect) / widthOfRadius;

    fh = CGRectGetHeight(rect) / heightOfRadius;

    

    CGContextMoveToPoint(contextRef, fw, fh/2);  // Start at lower right corner

    CGContextAddArcToPoint(contextRef, fw, fh, fw/2, fh, 1);  // Top right corner

    CGContextAddArcToPoint(contextRef, 0, fh, 0, fh/2, 1); // Top left corner

    CGContextAddArcToPoint(contextRef, 0, 0, fw/2, 0, 1); // Lower left corner

    CGContextAddArcToPoint(contextRef, fw, 0, fw, fh/2, 1); // Back to lower right

    

    CGContextClosePath(contextRef);

    CGContextRestoreGState(contextRef);

}

#pragma mark - Public Methods1

+ (UIImage *)createRoundedRectImage:(UIImage *)image withSize:(CGSize)size withRadius:(NSInteger)radius {

    int w = size.width;

    int h = size.height;

    

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();

    CGContextRef contextRef = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpaceRef, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);

    CGRect rect = CGRectMake(0, 0, w, h);

    

    CGContextBeginPath(contextRef);

    addRoundedRectToPath(contextRef, rect, radius, radius);

    CGContextClosePath(contextRef);

    CGContextClip(contextRef);

    CGContextDrawImage(contextRef, CGRectMake(0, 0, w, h), image.CGImage);

    CGImageRef imageMasked = CGBitmapContextCreateImage(contextRef);

    UIImage *img = [UIImage imageWithCGImage:imageMasked];

    

    CGContextRelease(contextRef);

    CGColorSpaceRelease(colorSpaceRef);

    CGImageRelease(imageMasked);

    return img;

}


@end



使用

 //用于生成二维码的字符串source

    NSString *source = @"https://github.com/KenmuHuang";

    

    CIImage *imgQRCode = [KMQRCode createQRCodeImage:source];

    

    UIImage *imgAdaptiveQRCode = [KMQRCode resizeQRCodeImage:imgQRCode

                                                    withSize:_imgVQRCode.frame.size.width];

    UIImage *imgIcon = [UIImage createRoundedRectImage:[UIImage imageNamed:@"logo"]

                                              withSize:CGSizeMake(70, 70)

                                            withRadius:10];

    imgAdaptiveQRCode = [KMQRCode addIconToQRCodeImage:imgAdaptiveQRCode

                                              withIcon:imgIcon

                                          withIconSize:imgIcon.size];

    

    

    _imgVQRCode.image = imgAdaptiveQRCode;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值