CodeHandlerObject.m 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //
  2. // CodeHandlerObject.m
  3. // MIT_Endorsement
  4. //
  5. // Created by 翟玉磊 on 2017/10/13.
  6. // Copyright © 2017年 翟玉磊. All rights reserved.
  7. //
  8. #import "CodeHandlerObject.h"
  9. @implementation CodeHandlerObject
  10. + (UIImage *)createCodeWithUrl:(NSString *)url withSize:(CGFloat)size {
  11. // 1. 实例化二维码滤镜
  12. CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  13. // 2. 恢复滤镜的默认属性
  14. [filter setDefaults];
  15. // 3. 将字符串转换成NSData
  16. // NSString *urlStr = @"http://www.ychpay.com/down.html";//测试二维码地址,次二维码不能支付,需要配合服务器来二维码的地址(跟后台人员配合)
  17. NSData *data = [url dataUsingEncoding:NSUTF8StringEncoding];
  18. // 4. 通过KVO设置滤镜inputMessage数据
  19. [filter setValue:data forKey:@"inputMessage"];
  20. // 5. 获得滤镜输出的图像
  21. CIImage *outputImage = [filter outputImage];
  22. // 6. 将CIImage转换成UIImage,并放大显示 (此时获取到的二维码比较模糊,所以需要用下面的createNonInterpolatedUIImageFormCIImage方法重绘二维码)
  23. // UIImage *codeImage = [UIImage imageWithCIImage:outputImage scale:1.0 orientation:UIImageOrientationUp];
  24. UIImage *codeImage = [CodeHandlerObject createNonInterpolatedUIImageFormCIImage:outputImage withSize:size]; //重绘二维码,使其显示清晰
  25. return codeImage;
  26. }
  27. /**
  28. * 根据CIImage生成指定大小的UIImage
  29. *
  30. * @param image CIImage
  31. * @param size 图片宽度
  32. */
  33. + (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size
  34. {
  35. CGRect extent = CGRectIntegral(image.extent);
  36. CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
  37. // 1.创建bitmap;
  38. size_t width = CGRectGetWidth(extent) * scale;
  39. size_t height = CGRectGetHeight(extent) * scale;
  40. CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
  41. CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
  42. CIContext *context = [CIContext contextWithOptions:nil];
  43. CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
  44. CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
  45. CGContextScaleCTM(bitmapRef, scale, scale);
  46. CGContextDrawImage(bitmapRef, extent, bitmapImage);
  47. // 2.保存bitmap到图片
  48. CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
  49. CGContextRelease(bitmapRef);
  50. CGImageRelease(bitmapImage);
  51. return [UIImage imageWithCGImage:scaledImage];
  52. }
  53. + (UIImage *)codeImageAddLogoWithCodeImage:(UIImage *)codeImage withLogo:(UIImage *)logoImage {
  54. CGSize size = CGSizeMake(codeImage.size.width,codeImage.size.width);
  55. CGFloat logoWith = 40;
  56. UIGraphicsBeginImageContextWithOptions(size,NO,[UIScreen mainScreen].scale);//初始化画布
  57. [codeImage drawAtPoint:CGPointZero];//把条形码图片添加到画布中
  58. CGContextRef context = UIGraphicsGetCurrentContext();//画布上下文
  59. CGContextDrawPath(context,kCGPathStroke);
  60. [codeImage drawInRect:CGRectMake(0,0,size.width,size.width)];
  61. [logoImage drawInRect:CGRectMake((size.width - logoWith) / 2,(size.height - logoWith) / 2, logoWith, logoWith)];
  62. UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //将画布映射到图片对象
  63. UIGraphicsEndImageContext();//关闭画布
  64. return image;
  65. }
  66. //生成的图片
  67. + (UIImage *)snapshotViewFromRect:(CGRect)rect withCapInsets:(UIEdgeInsets)capInsets layer:(CALayer *)theLayer{
  68. UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
  69. CGContextRef currentContext = UIGraphicsGetCurrentContext();
  70. [theLayer renderInContext:currentContext];
  71. UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
  72. UIGraphicsEndImageContext();
  73. return snapshotImage;
  74. }
  75. //生成带圆角的logo,logo不带边框。
  76. + (UIImage *)createQRCodeImageWithString:(NSString *)url centerLogo:(UIImage *)centerLogo logoType:(QRCodeLogoType)logoType withSize:(CGFloat)imageWH {
  77. // NSLog(@"%@", filter);
  78. // 二维码过滤器
  79. CIFilter *filterImage = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  80. // 将二位码过滤器设置为默认属性
  81. [filterImage setDefaults];
  82. // 将文字转化为二进制
  83. NSData *dataImage = [url dataUsingEncoding:NSUTF8StringEncoding];
  84. // 打印输入的属性
  85. // NSLog(@"%@", filterImage.inputKeys);
  86. // KVC 赋值
  87. [filterImage setValue:dataImage forKey:@"inputMessage"];
  88. // 取出输出图片
  89. CIImage *outputImage = [filterImage outputImage];
  90. outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
  91. // 转化图片
  92. UIImage *image = [UIImage imageWithCIImage:outputImage];
  93. if (image == nil) {
  94. return nil;
  95. }
  96. //生成图片,并获取上下文,得到一个带头像的二维码图片
  97. image = [self createNewImage:image logoImage:centerLogo logoType:logoType withSize:imageWH];
  98. return image;
  99. }
  100. + (UIImage *)createNewImage:(UIImage *)theImage logoImage:(UIImage *)logoImage logoType:(QRCodeLogoType)logoType withSize:(CGFloat)imageWH {
  101. float width = imageWH;
  102. float height = imageWH;
  103. UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, width,height)];
  104. view.backgroundColor = [UIColor whiteColor];
  105. UIImageView *bacImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, width,height)];
  106. bacImageView.image = theImage;
  107. bacImageView.backgroundColor = [UIColor whiteColor];
  108. [view addSubview:bacImageView];
  109. //logoImage.size.width;
  110. if (logoImage) {
  111. float width_logo = width / 5; //logo太大识别不了二维码
  112. UIView *logoBacView = [[UIView alloc]initWithFrame:CGRectMake((width - width_logo)/2 , (height - width_logo)/2, width_logo + 10,width_logo + 10)];
  113. logoBacView.backgroundColor = [UIColor whiteColor];
  114. logoBacView.layer.masksToBounds = YES;
  115. [bacImageView addSubview:logoBacView];
  116. UIImageView *centerImgView = [[UIImageView alloc]initWithFrame:CGRectMake(5,5, width_logo,width_logo)];
  117. centerImgView.image = logoImage;
  118. centerImgView.layer.masksToBounds = YES;
  119. centerImgView.backgroundColor = [UIColor whiteColor];
  120. [logoBacView addSubview:centerImgView];
  121. //设置圆角
  122. float radius = 0;
  123. float radius_img = 0;
  124. if (logoType == QRCodeLogoType_Round) {
  125. radius = (width_logo + 10)/2;
  126. radius_img = width_logo/2;
  127. }else if (logoType == QRCodeLogoType_Radius){
  128. radius = 6;
  129. radius_img = 6;
  130. }else {
  131. radius = 0;
  132. radius_img = 0;
  133. }
  134. logoBacView.layer.cornerRadius = radius;
  135. centerImgView.layer.cornerRadius = radius_img;
  136. }
  137. //生成图片
  138. UIImage *img = [self snapshotViewFromRect:CGRectMake(0, 0, view.frame.size.width, view.frame.size.height) withCapInsets:UIEdgeInsetsZero layer:view.layer];
  139. return img;
  140. }
  141. /*
  142. 生成条形码
  143. @param source
  144. @return 生成条形码的CIImage对象
  145. */
  146. + (CIImage *)generateBarCodeImage:(NSString *)source {
  147. // iOS 8.0以上的系统才支持条形码的生成,iOS8.0以下使用第三方控件生成
  148. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  149. // 注意生成条形码的编码方式
  150. NSData *data = [source dataUsingEncoding: NSASCIIStringEncoding];
  151. CIFilter *filter = [CIFilter filterWithName:@"CICode128BarcodeGenerator"];
  152. [filter setValue:data forKey:@"inputMessage"];
  153. // 设置生成的条形码的上,下,左,右的margins的值
  154. [filter setValue:[NSNumber numberWithInteger:0] forKey:@"inputQuietSpace"];
  155. return filter.outputImage;
  156. }else{
  157. return nil;
  158. }
  159. }
  160. /**
  161. 调整生成的图片的大小
  162. @param image CIImage对象
  163. @param size 需要的UIImage的大小
  164. @return size大小的UIImage对象
  165. */
  166. + (UIImage *) resizeCodeImage:(CIImage *)image withSize:(CGSize)size {
  167. if (image) {
  168. CGRect extent = CGRectIntegral(image.extent);
  169. CGFloat scaleWidth = size.width/CGRectGetWidth(extent);
  170. CGFloat scaleHeight = size.height/CGRectGetHeight(extent);
  171. size_t width = CGRectGetWidth(extent) * scaleWidth;
  172. size_t height = CGRectGetHeight(extent) * scaleHeight;
  173. CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceGray();
  174. CGContextRef contentRef = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpaceRef, (CGBitmapInfo)kCGImageAlphaNone);
  175. CIContext *context = [CIContext contextWithOptions:nil];
  176. CGImageRef imageRef = [context createCGImage:image fromRect:extent];
  177. CGContextSetInterpolationQuality(contentRef, kCGInterpolationNone);
  178. CGContextScaleCTM(contentRef, scaleWidth, scaleHeight);
  179. CGContextDrawImage(contentRef, extent, imageRef);
  180. CGImageRef imageRefResized = CGBitmapContextCreateImage(contentRef);
  181. CGContextRelease(contentRef);
  182. CGImageRelease(imageRef);
  183. return [UIImage imageWithCGImage:imageRefResized];
  184. }else{
  185. return nil;
  186. }
  187. }
  188. @end