Alex Puray
Alex Puray
1,304 Points

Saving a rotated image with CGContextRotateCTM

I've been trying to save a rotated image with CGContextRotateCTM for about 2 weeks now but when I save the image it just reverts back to the original image not rotated. Could someone explain how CGContextRotateCTM works? because I just cant seem to figure it out and how I can implement it into my app so I can save a rotated image.

Any information is greatly appreciated.

4 Answers

Obviously since I can't see your code I don't know for sure what you're doing wrong, but here's a bit of background:

When you're dealing with CoreGraphics you need to deal with things called contexts. You can think of a context as a 2D space on which you can draw. It's very much like a canvas. When you call UIGraphicsBeginImageContextWithOptions you'll provide a CGSize, this will be the size of your canvas (context). By default the origin of your context is {0,0} or the top-left. That means any transformations you apply to the context will happen about that point. If you do a 90 degree clockwise rotation your context will now be off screen. To deal with this you'll need to translate the context so that your rotation happens about the center of the context.

CGRect contextRect = ... // You'll set this to a rect like {0,0,imageWidth,imageHeight}
CGPoint contextCenter = CGPointMake(CGRectGetMidX(contextRect), CGRectGetMidY(contextRect));
CGContextTranslateCTM(context, contextCenter.x, contextCenter.y);

Now that you've translated the context to the proper position you can rotate it.

CGContextRotateCTM(context, M_PI);

CoreGraphics deals with radians. Here we're rotating the image pi radians, or 180 degrees.

Now we need to translate the context back to its original place so that when we draw we don't just see a quarter of the image.

CGContextTranslateCTM(context, -contextCenter.x, -contextCenter.y);

It's important to translate the context as many points backwards in each axis as you did forwards, so we translate by the negative of contextCenter's two fields - x and y.

Now are context is all set up, and only now are we ready to draw our image. If you drew your image before rotating the context you wouldn't see anything change.

[image drawInRect:contextRect];
UIImage* rotatedImage = UIGraphicsGetImageFromCurrentImageContext();

Don't forget to clean up your context!

Alex Puray
Alex Puray
1,304 Points

Well I'm blending two images together. The first image is a photo the user has taken. The second image can be manipulated by the user... adjust size, pan around the screen, rotating the image, etc.But I can't get the second image to stay saved when rotated. I'm also unsure where to implement the code to save it. Heres my blending code.

- (UIImage *) blendImages {
    UIImage *photoImage = self.photoView.image ;
    UIImage *stacheImage = self.toeView.image;

    CGSize photoSize = CGSizeMake(photoImage.size.width, photoImage.size.height);

    UIGraphicsBeginImageContext( photoSize );

    [photoImage drawInRect:CGRectMake(0,0,photoSize.width,photoSize.height)];

    CGPoint origin = self.toeView.frame.origin;
    CGSize size = self.toeView.frame.size;

    CGFloat xScale = photoImage.size.width / self.view.bounds.size.width;
    CGFloat yScale = photoImage.size.height / (self.view.bounds.size.height-44);

    [stacheImage drawInRect:CGRectMake((origin.x * xScale), (origin.y * yScale),
                                    size.width * xScale, size.height * yScale)
               blendMode:kCGBlendModeNormal alpha:1.0];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();


    return newImage;
Alex Puray
Alex Puray
1,304 Points

Heres my rotation code.

- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer {

    recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
    recognizer.rotation = 0;

Alex Puray
Alex Puray
1,304 Points

Where will i implement this code? In my blending or my rotation code?