UIImage+QQCorner.m 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //
  2. // UIImage+QQCorner.m
  3. // QQCorner
  4. //
  5. // Created by 秦琦 on 2018/10/24.
  6. // Copyright © 2018 QinQi. All rights reserved.
  7. //
  8. #import "UIImage+QQCorner.h"
  9. #import "QQCornerModel.h"
  10. @implementation UIImage (QQCorner)
  11. static UIBezierPath * qq_pathWithCornerRadius(QQRadius radius, CGSize size) {
  12. CGFloat imgW = size.width;
  13. CGFloat imgH = size.height;
  14. UIBezierPath *path = [UIBezierPath bezierPath];
  15. //左下
  16. [path addArcWithCenter:CGPointMake(radius.downLeft, imgH - radius.downLeft) radius:radius.downLeft startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
  17. //左上
  18. [path addArcWithCenter:CGPointMake(radius.upLeft, radius.upLeft) radius:radius.upLeft startAngle:M_PI endAngle:M_PI_2 * 3 clockwise:YES];
  19. //右上
  20. [path addArcWithCenter:CGPointMake(imgW - radius.upRight, radius.upRight) radius:radius.upRight startAngle:M_PI_2 * 3 endAngle:0 clockwise:YES];
  21. //右下
  22. [path addArcWithCenter:CGPointMake(imgW - radius.downRight, imgH - radius.downRight) radius:radius.downRight startAngle:0 endAngle:M_PI_2 clockwise:YES];
  23. [path closePath];
  24. return path;
  25. }
  26. + (UIImage *)imageWithGradualChangingColor:(void (^)(QQGradualChangingColor *))handler size:(CGSize)size cornerRadius:(QQRadius)radius {
  27. QQGradualChangingColor *graColor = [[QQGradualChangingColor alloc] init];
  28. if (handler) {
  29. handler(graColor);
  30. }
  31. CAGradientLayer *graLayer = [CAGradientLayer layer];
  32. graLayer.frame = (CGRect){CGPointZero, size};
  33. CGFloat startX = 0, startY = 0, endX = 0, endY = 0;
  34. switch (graColor.type) {
  35. case QQGradualChangeTypeUpLeftToDownRight: {
  36. startX = 0;
  37. startY = 0;
  38. endX = 1;
  39. endY = 1;
  40. }
  41. break;
  42. case QQGradualChangeTypeUpToDown: {
  43. startX = 0;
  44. startY = 0;
  45. endX = 0;
  46. endY = 1;
  47. }
  48. break;
  49. case QQGradualChangeTypeLeftToRight: {
  50. startX = 0;
  51. startY = 0;
  52. endX = 1;
  53. endY = 0;
  54. }
  55. break;
  56. case QQGradualChangeTypeUpRightToDownLeft: {
  57. startX = 0;
  58. startY = 1;
  59. endX = 1;
  60. endY = 0;
  61. }
  62. break;
  63. }
  64. graLayer.startPoint = CGPointMake(startX, startY);
  65. graLayer.endPoint = CGPointMake(endX, endY);
  66. graLayer.colors = @[(__bridge id)graColor.fromColor.CGColor, (__bridge id)graColor.toColor.CGColor];
  67. graLayer.locations = @[@0.0, @1.0];
  68. return [self imageWithLayer:graLayer cornerRadius:radius];
  69. }
  70. + (UIImage *)imageWithQQCorner:(void (^)(QQCorner *))handler size:(CGSize)size {
  71. QQCorner *corner = [[QQCorner alloc] init];
  72. if (handler) {
  73. handler(corner);
  74. }
  75. if (!corner.fillColor) {
  76. corner.fillColor = [UIColor clearColor];
  77. }
  78. UIBezierPath *path = qq_pathWithCornerRadius(corner.radius, size);
  79. if (@available(iOS 10.0, *)) {
  80. UIGraphicsImageRenderer *render = [[UIGraphicsImageRenderer alloc] initWithSize:size];
  81. return [render imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
  82. CGContextSetStrokeColorWithColor(rendererContext.CGContext, corner.borderColor.CGColor);
  83. CGContextSetFillColorWithColor(rendererContext.CGContext, corner.fillColor.CGColor);
  84. CGContextSetLineWidth(rendererContext.CGContext, corner.borderWidth);
  85. [path addClip];
  86. CGContextAddPath(rendererContext.CGContext, path.CGPath);
  87. CGContextDrawPath(rendererContext.CGContext, kCGPathFillStroke);
  88. }];
  89. } else {
  90. UIGraphicsBeginImageContext(size);
  91. CGContextRef context = UIGraphicsGetCurrentContext();
  92. CGContextSetStrokeColorWithColor(context, corner.borderColor.CGColor);
  93. CGContextSetFillColorWithColor(context, corner.fillColor.CGColor);
  94. CGContextSetLineWidth(context, corner.borderWidth);
  95. CGContextAddPath(context, path.CGPath);
  96. [path addClip];
  97. CGContextDrawPath(context, kCGPathFillStroke);
  98. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  99. UIGraphicsEndImageContext();
  100. return image;
  101. }
  102. }
  103. - (UIImage *)imageByAddingCornerRadius:(QQRadius)radius {
  104. UIBezierPath *path = qq_pathWithCornerRadius(radius, self.size);
  105. if (@available(iOS 10.0, *)) {
  106. UIGraphicsImageRenderer *render = [[UIGraphicsImageRenderer alloc] initWithSize:self.size];
  107. return [render imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
  108. [path addClip];
  109. CGContextAddPath(rendererContext.CGContext, path.CGPath);
  110. [self drawInRect:(CGRect){CGPointZero, self.size}];
  111. }];
  112. } else {
  113. UIGraphicsBeginImageContext(self.size);
  114. CGContextRef context = UIGraphicsGetCurrentContext();
  115. [path addClip];
  116. CGContextAddPath(context, path.CGPath);
  117. [self drawInRect:(CGRect){CGPointZero, self.size}];
  118. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  119. UIGraphicsEndImageContext();
  120. return image;
  121. }
  122. }
  123. + (UIImage *)imageWithColor:(UIColor *)color {
  124. return [self imageWithColor:color size:CGSizeMake(1, 1) cornerRadius:QQRadiusZero];
  125. }
  126. + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size cornerRadius:(QQRadius)radius {
  127. if (@available(iOS 10.0, *)) {
  128. UIGraphicsImageRenderer *render = [[UIGraphicsImageRenderer alloc] initWithSize:size];
  129. return [render imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
  130. if (!QQRadiusIsEqual(radius, QQRadiusZero)) {
  131. UIBezierPath *path = qq_pathWithCornerRadius(radius, size);
  132. [path addClip];
  133. CGContextAddPath(rendererContext.CGContext, path.CGPath);
  134. }
  135. CGContextSetFillColorWithColor(rendererContext.CGContext, color.CGColor);
  136. CGContextFillRect(rendererContext.CGContext, (CGRect){CGPointZero, size});
  137. }];
  138. } else {
  139. UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
  140. CGContextRef context = UIGraphicsGetCurrentContext();
  141. if (!QQRadiusIsEqual(radius, QQRadiusZero)) {
  142. UIBezierPath *path = qq_pathWithCornerRadius(radius, size);
  143. [path addClip];
  144. CGContextAddPath(context, path.CGPath);
  145. }
  146. CGContextSetFillColorWithColor(context, color.CGColor);
  147. CGContextFillRect(context, (CGRect){CGPointZero, size});
  148. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  149. UIGraphicsEndImageContext();
  150. return image;
  151. }
  152. }
  153. + (UIImage *)imageWithLayer:(CALayer *)layer cornerRadius:(QQRadius)radius {
  154. if (@available(iOS 10.0, *)) {
  155. UIGraphicsImageRenderer *render = [[UIGraphicsImageRenderer alloc] initWithSize:layer.bounds.size];
  156. return [render imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
  157. if (!QQRadiusIsEqual(radius, QQRadiusZero)) {
  158. UIBezierPath *path = qq_pathWithCornerRadius(radius, layer.bounds.size);
  159. [path addClip];
  160. CGContextAddPath(rendererContext.CGContext, path.CGPath);
  161. }
  162. [layer renderInContext:rendererContext.CGContext];
  163. }];
  164. } else {
  165. UIGraphicsBeginImageContext(layer.bounds.size);
  166. CGContextRef context = UIGraphicsGetCurrentContext();
  167. if (!QQRadiusIsEqual(radius, QQRadiusZero)) {
  168. UIBezierPath *path = qq_pathWithCornerRadius(radius, layer.bounds.size);
  169. [path addClip];
  170. CGContextAddPath(context, path.CGPath);
  171. }
  172. [layer renderInContext:context];
  173. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  174. UIGraphicsEndImageContext();
  175. return image;
  176. }
  177. }
  178. @end