Rotate UIImage produces a flipped image - ios

I'm just trying to rotate a UIImage around its center using the following piece of code:
- (UIImage *) rotateImage: (UIImage *)image angle:(CGFloat)angleInRadian
{
float newSide = MAX([image size].width, [image size].height);
CGSize size = CGSizeMake(newSide, newSide);
UIGraphicsBeginImageContext(size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, newSide/2, newSide/2);
CGContextRotateCTM(ctx, angleInRadian);
CGContextDrawImage(UIGraphicsGetCurrentContext(),CGRectMake(-[image size].width/2,-[image size].height/2,size.width, size.height),image.CGImage);
//CGContextTranslateCTM(ctx, [image size].width/2, [image size].height/2);
UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return i;
}
Here is a sample of the results I got:
Input image:
Result Image for angle = 0 radians :
The result image is flipped but I'm not sure why? Any idea about what I'm doing wrong?
Thanks in advance.

Add this line after CGContextRotateCTM
CGContextScaleCTM(ctx, 1.0, -1.0);
UIKit coordinate system is upside down to Quartz coordinate system. See here for more details
https://developer.apple.com/library/ios/qa/qa1708/_index.html
Also check image orientation.

Seems a bit overkill for what you want. Have you tried looking at CGAffineTransformRotate:
CGAffineTransformRotate(rotation.view.transform, angle);

Related

Merging two images of different size with rotate and zoom

I'm facing the following problem : I have to merge two images bottomImg and topImg to create a new image C as a result of the merging.
I already know how to merge two images but in this case my goal is a little bit different.
top image may be zoomed and rotated.
I have follow this answer. But in this solution top image is cut while i rotate. simulator
actual stored image is document like
I have try this code
_parentViewGIf for bottomImg and for _ivGIF for topImg
- (UIImage *)mergeImage:(UIImage *)bottomImg withImage:(UIImage *)topImg {
float width=bottomImg.size.width*_ivGIF.frame.size.width/_parentViewGIf.frame.size.width;
float height=bottomImg.size.width*_ivGIF.frame.size.height/_parentViewGIf.frame.size.width;
UIImage * scaledTopImg = [self imageByScalingProportionallyWithImage:topImg ToSize:CGSizeMake(bottomImg.size.width, bottomImg.size.height)];
UIGraphicsBeginImageContext(scaledTopImg.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, scaledTopImg.size.height * 0.5, scaledTopImg.size.height * 0.5);
CGFloat angle = atan2(_ivGIF.transform.a, _ivGIF.transform.b);
CGContextRotateCTM(ctx, angle);
[scaledTopImg drawInRect:CGRectMake(- scaledTopImg.size.width * 0.5f, -(scaledTopImg.size.height * 0.5f), scaledTopImg.size.width , scaledTopImg.size.height )];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
float x=bottomImg.size.width*_ivGIF.frame.origin.x/_parentViewGIf.frame.size.width;
float y=bottomImg.size.width*_ivGIF.frame.origin.y/_parentViewGIf.frame.size.width;
UIGraphicsBeginImageContext(bottomImg.size);
[bottomImg drawInRect:CGRectMake(0, 0, bottomImg.size.width, bottomImg.size.height)];
[newImage drawInRect:CGRectMake(0, 0, newImage.size.width, newImage.size.height)];
UIImage *newImage2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage2;
}
Thanks in advance for any help or suggestion

Rotate UIImage without quality loss

I have a problem to rotate UIImage without quality loss. Now I am using ready method provided by BFKit imageRotatedByDegrees:, but my image become diffused (blurred).
Sample code:
UIImage *image = [[UIImage imageNamed:#"car"] imageRotatedByDegrees:(((float)arc4random() / ARC4RANDOM_MAX) * (360))];
Code of imageRotatedByDegrees: :
- (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;
}
Is there another way to rotate UIImage without quality loss?
I'm the author of BFKit, and when I read about your question I investigated about that issue.
In the latest version (1.6.4) I've fixed that!
Now the image will no more be diffused (blurred).
My aim was to rotate an image that was in my MKAnnotationView. So I solved the problem by rotating not image, but whole MKAnnotationView.
An answer which helped me is this.
My code in MKMapViewDelegate method mapView:viewForAnnotation::
annotationView.transform = CGAffineTransformMakeRotation((((float)arc4random() / ARC4RANDOM_MAX) * (360)));

error rotating image by 90 in ios

I am using the following code to rotate an image -
- (UIImage *)rotateImage:(UIImage*)image byDegree:(CGFloat)degrees
{
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,image.size.width, image.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(M_PI/2);
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
CGContextRotateCTM(bitmap, M_PI/2);
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-image.size.width/2, -image.size.height/2, image.size.width, image.size.height), [image CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
My original image is -
When I hit rotate, it does not rotate well -
This kind of behavior happens only when the image is in the portrait mode i.e. (image.imageOrientation == UIImageOrientationLeft || image.imageOrientation == UIImageOrientationRight) . Landscape mode images are rotating well.
How can I edit the code to take care of both situations ?
When your image is in portrait, do not apply the rotation (or apply a π-rotation). You do not need to change the rotateImage implementation, just the way you call it.
I think there is problem with UIImageOrientationLeft and UIImageOrientationRight, all other i.e UIImageOrientationUp and UIImageOrientationDown comes the same way they looks.
I think there is no problem in the code, don’t use UIImageOrientationLeft and UIImageOrientationRight. Problem will be solved.

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?
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];
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;
}
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.

Rotate UIImage or UIImageView custom degree

i want rotate a UIImage or a UIImageView, i have tried a lot of code, and search everywhere, but i can't find a valid solution, i'm explain the problem, i download a image from the web and then i resize it in this way:
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
//UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
and the resize work very well, then
i have attached my UIImage at my UIImageView and then i have rotate my UIImageView in this way:
self.myImageView.transform = CGAffineTransformMakeRotation(degreesToRadian(-2));
but in this way the border are pixelled and there is aliasing, so i have tried to rotate first the UIImage and then give the image to my UIImageView, and i have find a lot of similar code, in particular i use this class Extension:
http://www.catamount.com/forums/viewtopic.php?f=21&t=967
and in this way, the border are antialised but instead loss quality the image, it's more fuzzy, and it's not sharp like first of rotate it, anyone have a good solution?
thanks...
for rotate image.. you can use this IBAction ... for each and every button click, the image will be rotate by 90 degree...
-(IBAction)rotateImageClick:(id)sender{
UIImage *image2=[[UIImage alloc]init];
image2 = [self imageRotatedByDegrees:self.roateImageView.image deg:(90)]; //Angle by 90 degree
self.roateImageView.image = image2;
imgData= UIImageJPEGRepresentation(image2,0.9f);
}
for rotating image u only have to pass UIimage and rotating degrees for the following method
- (UIImage *)imageRotatedByDegrees:(UIImage*)oldImage deg:(CGFloat)degrees
//------------------------------------------------------------------------
#pragma mark - imageRotatedByDegrees Method
- (UIImage *)imageRotatedByDegrees:(UIImage*)oldImage deg:(CGFloat)degrees{
// calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,oldImage.size.width, oldImage.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(degrees * M_PI / 180);
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, (degrees * M_PI / 180));
// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-oldImage.size.width / 2, -oldImage.size.height / 2, oldImage.size.width, oldImage.size.height), [oldImage CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
I think this link will be help.......! Rotate Original Image by clicking button in Objective C
http://adrianmobileapplication.blogspot.com/2015/03/rotate-original-image-by-clicking.html

Resources