二维码图片生成(扩展知识:创建带圆角效果的图片)
2015-06-14 13:52
489 查看
效果如下:
ViewController.h
ViewController.m
UIImage+RoundedRectImage.h
UIImage+RoundedRectImage.m
KMQRCode.h
KMQRCode.m
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (strong, nonatomic) IBOutlet UIImageView *imgVQRCode; @end
ViewController.m
#import "ViewController.h" #import "KMQRCode.h" #import "UIImage+RoundedRectImage.h" @interface ViewController () - (void)layoutUI; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self layoutUI]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)layoutUI { //用于生成二维码的字符串source NSString *source = @"https://github.com/KenmuHuang"; //使用iOS 7后的CIFilter对象操作,生成二维码图片imgQRCode(会拉伸图片,比较模糊,效果不佳) CIImage *imgQRCode = [KMQRCode createQRCodeImage:source]; //使用核心绘图框架CG(Core Graphics)对象操作,进一步针对大小生成二维码图片imgAdaptiveQRCode(图片大小适合,清晰,效果好) UIImage *imgAdaptiveQRCode = [KMQRCode resizeQRCodeImage:imgQRCode withSize:_imgVQRCode.frame.size.width]; //默认产生的黑白色的二维码图片;我们可以让它产生其它颜色的二维码图片,例如:蓝白色的二维码图片 imgAdaptiveQRCode = [KMQRCode specialColorImage:imgAdaptiveQRCode withRed:33.0 green:114.0 blue:237.0]; //0~255 //使用核心绘图框架CG(Core Graphics)对象操作,创建带圆角效果的图片 UIImage *imgIcon = [UIImage createRoundedRectImage:[UIImage imageNamed:@"QRCode"] withSize:CGSizeMake(70.0, 93.0) withRadius:10]; //使用核心绘图框架CG(Core Graphics)对象操作,合并二维码图片和用于中间显示的图标图片 imgAdaptiveQRCode = [KMQRCode addIconToQRCodeImage:imgAdaptiveQRCode withIcon:imgIcon withIconSize:imgIcon.size]; // imgAdaptiveQRCode = [KMQRCode addIconToQRCodeImage:imgAdaptiveQRCode // withIcon:imgIcon // withScale:3]; _imgVQRCode.image = imgAdaptiveQRCode; //设置图片视图的圆角边框效果 _imgVQRCode.layer.masksToBounds = YES; _imgVQRCode.layer.cornerRadius = 10.0; _imgVQRCode.layer.borderColor = [UIColor lightGrayColor].CGColor; _imgVQRCode.layer.borderWidth = 4.0; } @end
UIImage+RoundedRectImage.h
#import <UIKit/UIKit.h> @interface UIImage (RoundedRectImage) + (UIImage *)createRoundedRectImage:(UIImage *)image withSize:(CGSize)size withRadius:(NSInteger)radius; @end
UIImage+RoundedRectImage.m
#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 Methods + (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
KMQRCode.h
#import <UIKit/UIKit.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
KMQRCode.m
#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
相关文章推荐
- hibernate 离线查询 在线查询
- 如何用IP代理更换本机上网IP地址
- QT使用的积累(2015年7月3日更新)
- C++ vector用法小记
- BASE64编码和解码
- Servlet会话管理——Cookie会话跟踪
- mongoDB报错Cannot find module '../build/Release/bson'
- 关于cocos3.3移植android后清空UserDefault.xml数据的问题
- 51nod 1341 混合序列
- Cocos2d-x的学习之旅(五)菜单按钮
- php+MySQL图书管理系统(三)
- Linux系统编程——线程池
- [转载]常用 SQL Server 规范集锦
- ANSI GB2312 GBK UTF的关系
- 这样傻的事再也不会出现了
- The source attachment does not contain the source for the file xxx class
- 【.NET基础】--委托、事件、线程(2)
- C++11特性(02)匿名函数
- hive-学习笔记
- Realm数据库