Alessandro
Alessandro

Reputation: 4110

Rotating a UIImageView by angles

I want to rotate a UIImageView with the press of a button. I am using this code:

#import "UIImage-Extensions.h"
UIImage *rotatedImage = [SplashItGroupPicker.image imageRotatedByDegrees:360/arrayCount];
SplashItGroupPicker.image = rotatedImage;

and in "UIImage-Extensions.h" i have:

@interface UIImage (CS_Extensions)
- (UIImage *)imageRotatedByRadians:(CGFloat)radians;
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;

and in the .m:

- (UIImage *)imageRotatedByRadians:(CGFloat)radians
{
return [self imageRotatedByDegrees:RadiansToDegrees(radians)];
}

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

// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize);
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, DegreesToRadians(degrees));

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

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;

}

...the rotation works fine, but when the image is rotated, the image also gets smaller and I can't understand why. Any ideas?

Upvotes: 1

Views: 1055

Answers (3)

Mohit Tomar
Mohit Tomar

Reputation: 5211

There is no need to UIGraphicsGetImageFromCurrentImageContext. its a way to get screenshot of desired portion of mainscreen. so the result image quality affected. the only way to get Rotated Image is...

first rotate your image view by(if you want to show rotated view)

[mainImgV setTransform:CGAffineTransformRotate(mainImgV.transform, M_PI)];

it will rotate your imageview. now you will take this rotated image by these lines.(you can call these lines without rotate imgaeview also.)

 CGImageRef cgRef = mainImgV.image.CGImage;
    newImage = [[UIImage alloc] initWithCGImage:cgRef scale:1.0 orientation:UIImageOrientationDown];

there is no need to save or take screenshot or compromise bad quality image. just enjoy coding.

Upvotes: 0

RyanG
RyanG

Reputation: 4503

Using Kekoa's snippet (thanks a ton), I was able to get a working rotateImage function that works on retina devices based on Apples rotateImage code:

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees {
    CGFloat radians = DegreesToRadians(degrees);

    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(radians);
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, [[UIScreen mainScreen] scale]);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);

    CGContextRotateCTM(bitmap, radians);

    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2 , self.size.width, self.size.height), self.CGImage );

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Upvotes: 0

Kekoa
Kekoa

Reputation: 28250

Here's a guess, is this only happening on Retina screens? Whenever saving a UIImage from a graphics context, you need to make sure the scale is correct. This is how I have done it:

CGFloat scale = [[UIScreen mainScreen] scale];
CGSize size = CGSizeMake(rotatedViewBox.frame.size.width * scale, rotatedViewBox.frame.size.height * scale);

UIGraphicsBeginImageContext( size );

/* Do your image manipulations here */

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// overwrite the image with one that has the correct scale set
newImage = [UIImage imageWithCGImage:newImage.CGImage scale:scale orientation:newImage.imageOrientation];

Upvotes: 2

Related Questions