0

I am using the following code to achieve this. The problem is when the image is rotated it scales the image the nearer the degree is to 45'.

When the image is set to 90' and its multiples there is no problem with the image size. But when the degree gets close to 45' and its multiples there is a noticeable shrink in the image size. I do not want to change the image size. How should I approach this problem?

- (UIImage *)imageRotatedByRadians:(CGFloat)radians img:(UIImage *)img
{
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,img.size.width, img.size.height)];
    UIView *nonrotatedViewBox = rotatedViewBox;
    CGAffineTransform t = CGAffineTransformMakeRotation(radians);
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    UIGraphicsBeginImageContext(nonrotatedViewBox.frame.size);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //Rotate the image context
    CGContextRotateCTM(bitmap, radians);

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-img.size.width / 2, -img.size.height / 2, img.size.width, img.size.height), [img CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
user1118321
  • 25,567
  • 4
  • 55
  • 86
Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
  • 1
    Do you have to rotate an image or can you rotate a UIImageView and that will fix your problem. Also... the dimensions of your view are wrong, you don't want to draw the image in the width and height divided by 2. Because when an image is rotated it's width becomes (when referring to a perfect square) is the width times 2 times sqr(2). so if you had a width and height of like 10 then your new width (at a 45 degree angle) would be between 14 and 15... so your context is drawing a 14x14 image in a 10x10 area – A'sa Dickens May 13 '14 at 13:46
  • you could go through some complicated math to get the perfect dimensions using geometry, or you could wing it and say | double percentRotated = (radians % M_PI_4)/M_PI_4; double newWidth = (percentRotated == 0 ? img.size.width : img.size.width * (1 + percentRotated) ); and do the same thing for the height – A'sa Dickens May 13 '14 at 13:51
  • I need to rotate the image, because I am going to save it. My image is a perfect square I will try changing the width. – Esqarrouth May 13 '14 at 13:56
  • it's hard to explain via text, so due this test, take a 100x100 image, in your code don't rotate it and set the bounds to be 100x100 then rotate it by 45 degrees or PI/4 radians, and then pass in 141x141 for the width/height and see if it looks correct, from there you will probably see what i'm talking about :3 – A'sa Dickens May 13 '14 at 14:04
  • CGFloat newsize = sqrtf((img.size.width * img.size.width)*2); ---- CGContextDrawImage(bitmap, CGRectMake(-img.size.width / 2, -img.size.height / 2, newsize, newsize), [img CGImage]); ------ I did this now the image size is correct. The problem is the image is now leaned to the right side, cutting off a portion of the image. Any ideas with this? – Esqarrouth May 13 '14 at 14:15
  • am i clear or do i need to post images? – Esqarrouth May 13 '14 at 14:17
  • nvm solved it with this, CGContextDrawImage(bitmap, CGRectMake(-newsize / 2, -newsize / 2, newsize, newsize), [img CGImage]); you can make the answer offical – Esqarrouth May 13 '14 at 14:24
  • oh okay i will make the official answer – A'sa Dickens May 13 '14 at 15:51

1 Answers1

1

the dimensions of your view are wrong, you don't want to draw the image in the width and height divided by 2. Because when an image is rotated it's width becomes (when referring to a perfect square) is the width times 2 times sqr(2). so if you had a width and height of like 10 then your new width (at a 45 degree angle) would be between 14 and 15... so your context is drawing a 14x14 image in a 10x10 area

you could go through some complicated math to get the perfect dimensions using geometry, or you could wing it and say | double percentRotated = (radians % M_PI_4)/M_PI_4; double newWidth = (percentRotated == 0 ? img.size.width : img.size.width * (1 + (percentRotated % 0.25)) ); and do the same thing for the height, #lazyprogrammer

A'sa Dickens
  • 2,045
  • 1
  • 16
  • 21
  • although looking at my answer, the MAX dimensions will only be experienced at 45% so that (1 + percentRotated) will mess him up XD so he should do the percentRotated%25 meaning it's in increments of max distance of π/4 – A'sa Dickens Nov 10 '14 at 15:58