Arbitrary rotation of a CGImage

For my current project, I have to rotate a CGImageRef by an arbitrary angle.

Here is the code:


- (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
{ 
  CGFloat angleInRadians = angle * (M_PI / 180);
  CGFloat width = CGImageGetWidth(imgRef);
  CGFloat height = CGImageGetHeight(imgRef);

  CGRect imgRect = CGRectMake(0, 0, width, height);
  CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
  CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef bmContext = CGBitmapContextCreate(NULL, 
                                                 rotatedRect.size.width, 
                                                 rotatedRect.size.height, 
                                                 8, 
                                                 0, 
                                                 colorSpace, 
                                                 kCGImageAlphaPremultipliedFirst);
  CGContextSetAllowsAntialiasing(bmContext, FALSE);
  CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone);
  CGColorSpaceRelease(colorSpace);
  CGContextTranslateCTM(bmContext, 
                        +(rotatedRect.size.width/2), 
                        +(rotatedRect.size.height/2));
  CGContextRotateCTM(bmContext, angleInRadians);
  CGContextTranslateCTM(bmContext, 
                        -(rotatedRect.size.width/2), 
                        -(rotatedRect.size.height/2));
  CGContextDrawImage(bmContext, CGRectMake(0, 0, 
                                           rotatedRect.size.width, 
                                           rotatedRect.size.height), 
                     imgRef);

  CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
  CFRelease(bmContext);
  [(id)rotatedImage autorelease];

  return rotatedImage;
}

7 thoughts on “Arbitrary rotation of a CGImage

  1. Pingback: NSCoriolisBlog » Blog Archive » Arbitrary rotation of a CGImage « Connor Denman's Blog

  2. Pingback: 9-slice scaling/stretching in the background, using Cocoa on iOS. | taking a bite into Apple

  3. Here is the working version for everyone else that stumbles upon this awesome function but finds it to be broke like I did.


    - (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
    {
    CGFloat angleInRadians = angle * (M_PI / 180);
    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGRect imgRect = CGRectMake(0, 0, width, height);
    CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
    CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bmContext = CGBitmapContextCreate(NULL,
    rotatedRect.size.width,
    rotatedRect.size.height,
    8,
    0,
    colorSpace,
    kCGImageAlphaPremultipliedFirst);
    CGContextSetAllowsAntialiasing(bmContext, TRUE);
    CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone);
    CGColorSpaceRelease(colorSpace);
    CGContextTranslateCTM(bmContext,
    +(rotatedRect.size.width/2),
    +(rotatedRect.size.height/2));
    CGContextRotateCTM(bmContext, angleInRadians);
    CGContextTranslateCTM(bmContext,
    -(rotatedRect.size.width/2),
    -(rotatedRect.size.height/2));
    CGContextDrawImage(bmContext,
    CGRectMake((rotatedRect.size.width-width)/2.0f,
    (rotatedRect.size.height-height)/2.0f,
    width,
    height),
    imgRef);

    CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
    CFRelease(bmContext);
    return rotatedImage;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*