QRImage.m 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // QRImage.m
  3. // shiku_im
  4. //
  5. // Created by 1 on 17/9/14.
  6. // Copyright © 2017年 Reese. All rights reserved.
  7. //
  8. #import "QRImage.h"
  9. @implementation QRImage
  10. //标准二维码
  11. + (UIImage *)qrImageForString:(NSString *)string imageSize:(CGFloat)Imagesize{
  12. CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  13. [filter setDefaults];
  14. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  15. [filter setValue:data forKey:@"inputMessage"];//通过kvo方式给一个字符串,生成二维码
  16. [filter setValue:@"H" forKey:@"inputCorrectionLevel"];//设置二维码的纠错水平,越高纠错水平越高,可以污损的范围越大
  17. CIImage *outPutImage = [filter outputImage];//拿到二维码图片
  18. return [[self alloc] createNonInterpolatedUIImageFormCIImage:outPutImage imageSize:Imagesize logoImage:nil logoImageSize:0];
  19. }
  20. //带中心头像二维码
  21. + (UIImage *)qrImageForString:(NSString *)string imageSize:(CGFloat)Imagesize logoImage:(UIImage *)logoImage logoImageSize:(CGFloat)logoImagesize{
  22. CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  23. [filter setDefaults];
  24. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  25. [filter setValue:data forKey:@"inputMessage"];//通过kvo方式给一个字符串,生成二维码
  26. [filter setValue:@"H" forKey:@"inputCorrectionLevel"];//设置二维码的纠错水平,越高纠错水平越高,可以污损的范围越大
  27. CIImage *outPutImage = [filter outputImage];//拿到二维码图片
  28. return [[self alloc] createNonInterpolatedUIImageFormCIImage:outPutImage imageSize:Imagesize logoImage:logoImage logoImageSize:logoImagesize];
  29. }
  30. /**
  31. * 生成条形码
  32. *
  33. * @return 生成条形码的UIImage对象
  34. */
  35. + (UIImage *)barCodeWithString:(NSString *)text BCSize:(CGSize)size
  36. {
  37. CIImage *image = [self generateBarCodeImage:text];
  38. return [self resizeCodeImage:image withSize:size];
  39. }
  40. + (CIImage *)generateBarCodeImage:(NSString *)source
  41. {
  42. // iOS 8.0以上的系统才支持条形码的生成,iOS8.0以下使用第三方控件生成
  43. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  44. // 注意生成条形码的编码方式
  45. NSData *data = [source dataUsingEncoding: NSASCIIStringEncoding];
  46. CIFilter *filter = [CIFilter filterWithName:@"CICode128BarcodeGenerator"];
  47. [filter setValue:data forKey:@"inputMessage"];
  48. // 设置生成的条形码的上,下,左,右的margins的值
  49. [filter setValue:[NSNumber numberWithInteger:0] forKey:@"inputQuietSpace"];
  50. return filter.outputImage;
  51. }else{
  52. return nil;
  53. }
  54. }
  55. + (UIImage *)resizeCodeImage:(CIImage *)image withSize:(CGSize)size
  56. {
  57. if (image) {
  58. CGRect extent = CGRectIntegral(image.extent);
  59. CGFloat scaleWidth = size.width/CGRectGetWidth(extent);
  60. CGFloat scaleHeight = size.height/CGRectGetHeight(extent);
  61. size_t width = CGRectGetWidth(extent) * scaleWidth;
  62. size_t height = CGRectGetHeight(extent) * scaleHeight;
  63. CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceGray();
  64. CGContextRef contentRef = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpaceRef, (CGBitmapInfo)kCGImageAlphaNone);
  65. CIContext *context = [CIContext contextWithOptions:nil];
  66. CGImageRef imageRef = [context createCGImage:image fromRect:extent];
  67. CGContextSetInterpolationQuality(contentRef, kCGInterpolationNone);
  68. CGContextScaleCTM(contentRef, scaleWidth, scaleHeight);
  69. CGContextDrawImage(contentRef, extent, imageRef);
  70. CGImageRef imageRefResized = CGBitmapContextCreateImage(contentRef);
  71. UIImage *barImage = [UIImage imageWithCGImage:imageRefResized];
  72. //Core Foundation 框架下内存泄露问题。
  73. CGContextRelease(contentRef);
  74. CGColorSpaceRelease(colorSpaceRef);
  75. CGImageRelease(imageRef);
  76. CGImageRelease(imageRefResized);
  77. return barImage;
  78. }else{
  79. return nil;
  80. }
  81. }
  82. - (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image imageSize:(CGFloat)imageSize logoImage:(UIImage *)logoImage logoImageSize:(CGFloat)logoImagesize{
  83. CGRect extent = CGRectIntegral(image.extent);
  84. CGFloat scale = MIN(imageSize/CGRectGetWidth(extent), imageSize/CGRectGetHeight(extent));
  85. // 1.创建bitmap;
  86. size_t width = CGRectGetWidth(extent) * scale;
  87. size_t height = CGRectGetHeight(extent) * scale;
  88. //创建一个DeviceGray颜色空间
  89. CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
  90. //CGBitmapContextCreate(void * _Nullable data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef _Nullable space, uint32_t bitmapInfo)
  91. //width:图片宽度像素
  92. //height:图片高度像素
  93. //bitsPerComponent:每个颜色的比特值,例如在rgba-32模式下为8
  94. //bitmapInfo:指定的位图应该包含一个alpha通道。
  95. CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
  96. CIContext *context = [CIContext contextWithOptions:nil];
  97. //创建CoreGraphics image
  98. CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
  99. CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
  100. CGContextScaleCTM(bitmapRef, scale, scale);
  101. CGContextDrawImage(bitmapRef, extent, bitmapImage);
  102. // 2.保存bitmap到图片
  103. CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
  104. CGContextRelease(bitmapRef); CGImageRelease(bitmapImage);
  105. //原图
  106. UIImage *outputImage = [UIImage imageWithCGImage:scaledImage];
  107. //给二维码加 logo 图
  108. UIGraphicsBeginImageContextWithOptions(outputImage.size, NO, [[UIScreen mainScreen] scale]);
  109. [outputImage drawInRect:CGRectMake(0,0 , imageSize, imageSize)];
  110. if (logoImage) {
  111. logoImage = [self logoImage:logoImage withParam:logoImagesize/2];
  112. //把logo图画到生成的二维码图片上,注意尺寸不要太大(最大不超过二维码图片的%30),太大会造成扫不出来
  113. [logoImage drawInRect:CGRectMake((imageSize-logoImagesize)/2.0, (imageSize-logoImagesize)/2.0, logoImagesize, logoImagesize)];
  114. }
  115. outputImage = UIGraphicsGetImageFromCurrentImageContext();
  116. UIGraphicsEndImageContext();
  117. return outputImage;
  118. }
  119. - (UIImage *)logoImage:(UIImage *)image withParam:(CGFloat)inset {
  120. UIImageView *imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, inset*2, inset*2)];
  121. imageV.image = image;
  122. imageV.layer.cornerRadius = inset;
  123. imageV.layer.masksToBounds = YES;
  124. imageV.layer.borderColor = [UIColor whiteColor].CGColor;
  125. imageV.layer.borderWidth = 3.f;
  126. UIImage *newImage = [UIImage imageWithView:imageV];
  127. return newImage;
  128. }
  129. @end