views:

382

answers:

1

This function rotates a CGImage by an arbitrary number of degrees, but it clips the image a bit. How can I avoid the clipping?

Making the rectangle a bit larger seems to distort the image being rotated.

+ (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle {

  float angleInRadians = angle * (M_PI / 180);
  float width = CGImageGetWidth(imgRef);
  float 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);
  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;
}
+1  A: 

Not sure I fully get this. These geometry questions are très très difficile.

But just looking at the geometry I would try:

  • Round the rotated width and height up to nearest pixel.

  • Don't do the second translate.

  • Check the sign of the first translate and the first and second angle rotation.

  • Plot the image at rectangle (-width/2, -height/2, width, height).

martinr