UIImage+Rotate.m 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. //
  2. // UIImage+Rotate.m
  3. // UIImage+Categories
  4. //
  5. // Created by lisong on 16/9/4.
  6. // Copyright © 2016年 lisong. All rights reserved.
  7. //
  8. #import "UIImage+Rotate.h"
  9. //由角度转换弧度
  10. #define kDegreesToRadian(x) (M_PI * (x) / 180.0)
  11. //由弧度转换角度
  12. #define kRadianToDegrees(radian) (radian * 180.0) / (M_PI)
  13. @implementation UIImage (Rotate)
  14. /** 纠正图片的方向 */
  15. - (UIImage *)fixOrientation
  16. {
  17. if (self.imageOrientation == UIImageOrientationUp) return self;
  18. // We need to calculate the proper transformation to make the image upright.
  19. // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
  20. CGAffineTransform transform = CGAffineTransformIdentity;
  21. switch (self.imageOrientation)
  22. {
  23. case UIImageOrientationDown:
  24. case UIImageOrientationDownMirrored:
  25. transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
  26. transform = CGAffineTransformRotate(transform, M_PI);
  27. break;
  28. case UIImageOrientationLeft:
  29. case UIImageOrientationLeftMirrored:
  30. transform = CGAffineTransformTranslate(transform, self.size.width, 0);
  31. transform = CGAffineTransformRotate(transform, M_PI_2);
  32. break;
  33. case UIImageOrientationRight:
  34. case UIImageOrientationRightMirrored:
  35. transform = CGAffineTransformTranslate(transform, 0, self.size.height);
  36. transform = CGAffineTransformRotate(transform, -M_PI_2);
  37. break;
  38. case UIImageOrientationUp:
  39. case UIImageOrientationUpMirrored:
  40. break;
  41. }
  42. switch (self.imageOrientation)
  43. {
  44. case UIImageOrientationUpMirrored:
  45. case UIImageOrientationDownMirrored:
  46. transform = CGAffineTransformTranslate(transform, self.size.width, 0);
  47. transform = CGAffineTransformScale(transform, -1, 1);
  48. break;
  49. case UIImageOrientationLeftMirrored:
  50. case UIImageOrientationRightMirrored:
  51. transform = CGAffineTransformTranslate(transform, self.size.height, 0);
  52. transform = CGAffineTransformScale(transform, -1, 1);
  53. break;
  54. case UIImageOrientationUp:
  55. case UIImageOrientationDown:
  56. case UIImageOrientationLeft:
  57. case UIImageOrientationRight:
  58. break;
  59. }
  60. // Now we draw the underlying CGImage into a new context, applying the transform
  61. // calculated above.
  62. CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
  63. CGImageGetBitsPerComponent(self.CGImage), 0,
  64. CGImageGetColorSpace(self.CGImage),
  65. CGImageGetBitmapInfo(self.CGImage));
  66. CGContextConcatCTM(ctx, transform);
  67. switch (self.imageOrientation)
  68. {
  69. case UIImageOrientationLeft:
  70. case UIImageOrientationLeftMirrored:
  71. case UIImageOrientationRight:
  72. case UIImageOrientationRightMirrored:
  73. CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
  74. break;
  75. default:
  76. CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
  77. break;
  78. }
  79. CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
  80. UIImage *img = [UIImage imageWithCGImage:cgimg];
  81. CGContextRelease(ctx);
  82. CGImageRelease(cgimg);
  83. return img;
  84. }
  85. /** 按给定的方向旋转图片 */
  86. - (UIImage*)rotate:(UIImageOrientation)orient
  87. {
  88. CGRect bnds = CGRectZero;
  89. UIImage* copy = nil;
  90. CGContextRef ctxt = nil;
  91. CGImageRef imag = self.CGImage;
  92. CGRect rect = CGRectZero;
  93. CGAffineTransform tran = CGAffineTransformIdentity;
  94. rect.size.width = CGImageGetWidth(imag);
  95. rect.size.height = CGImageGetHeight(imag);
  96. bnds = rect;
  97. switch (orient)
  98. {
  99. case UIImageOrientationUp:
  100. return self;
  101. case UIImageOrientationUpMirrored:
  102. tran = CGAffineTransformMakeTranslation(rect.size.width, 0.0);
  103. tran = CGAffineTransformScale(tran, -1.0, 1.0);
  104. break;
  105. case UIImageOrientationDown:
  106. tran = CGAffineTransformMakeTranslation(rect.size.width,
  107. rect.size.height);
  108. tran = CGAffineTransformRotate(tran, M_PI);
  109. break;
  110. case UIImageOrientationDownMirrored:
  111. tran = CGAffineTransformMakeTranslation(0.0, rect.size.height);
  112. tran = CGAffineTransformScale(tran, 1.0, -1.0);
  113. break;
  114. case UIImageOrientationLeft:
  115. bnds = swapWidthAndHeight(bnds);
  116. tran = CGAffineTransformMakeTranslation(0.0, rect.size.width);
  117. tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
  118. break;
  119. case UIImageOrientationLeftMirrored:
  120. bnds = swapWidthAndHeight(bnds);
  121. tran = CGAffineTransformMakeTranslation(rect.size.height,
  122. rect.size.width);
  123. tran = CGAffineTransformScale(tran, -1.0, 1.0);
  124. tran = CGAffineTransformRotate(tran, 3.0 * M_PI / 2.0);
  125. break;
  126. case UIImageOrientationRight:
  127. bnds = swapWidthAndHeight(bnds);
  128. tran = CGAffineTransformMakeTranslation(rect.size.height, 0.0);
  129. tran = CGAffineTransformRotate(tran, M_PI / 2.0);
  130. break;
  131. case UIImageOrientationRightMirrored:
  132. bnds = swapWidthAndHeight(bnds);
  133. tran = CGAffineTransformMakeScale(-1.0, 1.0);
  134. tran = CGAffineTransformRotate(tran, M_PI / 2.0);
  135. break;
  136. default:
  137. return self;
  138. }
  139. UIGraphicsBeginImageContext(bnds.size);
  140. ctxt = UIGraphicsGetCurrentContext();
  141. switch (orient)
  142. {
  143. case UIImageOrientationLeft:
  144. case UIImageOrientationLeftMirrored:
  145. case UIImageOrientationRight:
  146. case UIImageOrientationRightMirrored:
  147. CGContextScaleCTM(ctxt, -1.0, 1.0);
  148. CGContextTranslateCTM(ctxt, -rect.size.height, 0.0);
  149. break;
  150. default:
  151. CGContextScaleCTM(ctxt, 1.0, -1.0);
  152. CGContextTranslateCTM(ctxt, 0.0, -rect.size.height);
  153. break;
  154. }
  155. CGContextConcatCTM(ctxt, tran);
  156. CGContextDrawImage(UIGraphicsGetCurrentContext(), rect, imag);
  157. copy = UIGraphicsGetImageFromCurrentImageContext();
  158. UIGraphicsEndImageContext();
  159. return copy;
  160. }
  161. /** 垂直翻转 */
  162. - (UIImage *)flipVertical
  163. {
  164. return [self rotate:UIImageOrientationDownMirrored];
  165. }
  166. /** 水平翻转 */
  167. - (UIImage *)flipHorizontal
  168. {
  169. return [self rotate:UIImageOrientationUpMirrored];
  170. }
  171. /** 将图片旋转弧度radians */
  172. - (UIImage *)imageRotatedByRadians:(CGFloat)radians
  173. {
  174. // calculate the size of the rotated view's containing box for our drawing space
  175. UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
  176. CGAffineTransform t = CGAffineTransformMakeRotation(radians);
  177. rotatedViewBox.transform = t;
  178. CGSize rotatedSize = rotatedViewBox.frame.size;
  179. // Create the bitmap context
  180. UIGraphicsBeginImageContext(rotatedSize);
  181. CGContextRef bitmap = UIGraphicsGetCurrentContext();
  182. // Move the origin to the middle of the image so we will rotate and scale around the center.
  183. CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
  184. // // Rotate the image context
  185. CGContextRotateCTM(bitmap, radians);
  186. // Now, draw the rotated/scaled image into the context
  187. CGContextScaleCTM(bitmap, 1.0, -1.0);
  188. CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);
  189. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  190. UIGraphicsEndImageContext();
  191. return newImage;
  192. }
  193. /** 将图片旋转角度degrees */
  194. - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees
  195. {
  196. return [self imageRotatedByRadians:kDegreesToRadian(degrees)];
  197. }
  198. /** 交换宽和高 */
  199. static CGRect swapWidthAndHeight(CGRect rect)
  200. {
  201. CGFloat swap = rect.size.width;
  202. rect.size.width = rect.size.height;
  203. rect.size.height = swap;
  204. return rect;
  205. }
  206. @end