UIImage+Rotating.m 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. //
  2. // UIImage+Rotation.m
  3. // NYXImagesKit
  4. //
  5. // Created by @Nyx0uf on 02/05/11.
  6. // Copyright 2012 Nyx0uf. All rights reserved.
  7. // www.cocoaintheshell.com
  8. //
  9. #import "UIImage+Rotating.h"
  10. #import <QuartzCore/QuartzCore.h>
  11. #import <Accelerate/Accelerate.h>
  12. @implementation UIImage (NYX_Rotating)
  13. -(UIImage*)rotateInRadians:(CGFloat)radians flipOverHorizontalAxis:(BOOL)doHorizontalFlip verticalAxis:(BOOL)doVerticalFlip
  14. {
  15. /// Create an ARGB bitmap context
  16. const size_t width = (size_t)CGImageGetWidth(self.CGImage);
  17. const size_t height = (size_t)CGImageGetHeight(self.CGImage);
  18. CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0., 0., width, height), CGAffineTransformMakeRotation(radians));
  19. CGContextRef bmContext = NYXCreateARGBBitmapContext((size_t)rotatedRect.size.width, (size_t)rotatedRect.size.height, (size_t)rotatedRect.size.width * kNyxNumberOfComponentsPerARBGPixel);
  20. if (!bmContext)
  21. return nil;
  22. /// Image quality
  23. CGContextSetShouldAntialias(bmContext, true);
  24. CGContextSetAllowsAntialiasing(bmContext, true);
  25. CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
  26. /// Rotation happen here (around the center)
  27. CGContextTranslateCTM(bmContext, +(rotatedRect.size.width / 2.0f), +(rotatedRect.size.height / 2.0f));
  28. CGContextRotateCTM(bmContext, radians);
  29. // Do flips
  30. CGContextTranslateCTM(bmContext, (doHorizontalFlip ? width : 0.0f), (doVerticalFlip ? height : 0.0f));
  31. CGContextScaleCTM(bmContext, (doHorizontalFlip ? -1.0f : 1.0f), (doVerticalFlip ? -1.0f : 1.0f));
  32. /// Draw the image in the bitmap context
  33. CGContextDrawImage(bmContext, CGRectMake(-(width / 2.0f), -(height / 2.0f), width, height), self.CGImage);
  34. /// Create an image object from the context
  35. CGImageRef resultImageRef = CGBitmapContextCreateImage(bmContext);
  36. UIImage* resultImage = [UIImage imageWithCGImage:resultImageRef scale:self.scale orientation:self.imageOrientation];
  37. /// Cleanup
  38. CGImageRelease(resultImageRef);
  39. CGContextRelease(bmContext);
  40. return resultImage;
  41. }
  42. -(UIImage*)rotateInRadians:(float)radians
  43. {
  44. return [self rotateInRadians:radians flipOverHorizontalAxis:NO verticalAxis:NO];
  45. }
  46. -(UIImage*)rotateInDegrees:(float)degrees
  47. {
  48. return [self rotateInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)];
  49. }
  50. -(UIImage*)verticalFlip
  51. {
  52. return [self rotateInRadians:0. flipOverHorizontalAxis:NO verticalAxis:YES];
  53. }
  54. -(UIImage*)horizontalFlip
  55. {
  56. return [self rotateInRadians:0. flipOverHorizontalAxis:YES verticalAxis:NO];
  57. }
  58. -(UIImage*)rotateImagePixelsInRadians:(float)radians
  59. {
  60. /// Create an ARGB bitmap context
  61. const size_t width = (size_t)(self.size.width * self.scale);
  62. const size_t height = (size_t)(self.size.height * self.scale);
  63. const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel;
  64. CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow);
  65. if (!bmContext)
  66. return nil;
  67. /// Draw the image in the bitmap context
  68. CGContextDrawImage(bmContext, CGRectMake(0.0f, 0.0f, width, height), self.CGImage);
  69. /// Grab the image raw data
  70. UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext);
  71. if (!data)
  72. {
  73. CGContextRelease(bmContext);
  74. return nil;
  75. }
  76. vImage_Buffer src = {data, height, width, bytesPerRow};
  77. vImage_Buffer dest = {data, height, width, bytesPerRow};
  78. Pixel_8888 bgColor = {0, 0, 0, 0};
  79. vImageRotate_ARGB8888(&src, &dest, NULL, radians, bgColor, kvImageBackgroundColorFill);
  80. CGImageRef rotatedImageRef = CGBitmapContextCreateImage(bmContext);
  81. UIImage* rotated = [UIImage imageWithCGImage:rotatedImageRef scale:self.scale orientation:self.imageOrientation];
  82. /// Cleanup
  83. CGImageRelease(rotatedImageRef);
  84. CGContextRelease(bmContext);
  85. return rotated;
  86. }
  87. -(UIImage*)rotateImagePixelsInDegrees:(float)degrees
  88. {
  89. return [self rotateImagePixelsInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)];
  90. }
  91. @end