I know i have to translate the coordinate system, when drawing. The thing is that when i use:
CGContextTranslateCTM(_context, 0.0, _size.height);
CGContextScaleCTM(_context, 1.0, -1.0);
My rect of the image is flipped, and the image is 'non-flipped', if i dont use the above my image is flipped, and the rect is non-flipped.
Here's my code:
CGRectMake(60, 100, image.size.width, image.size.height);
CGContextSaveGState(_context);
UIGraphicsBeginImageContext(image.size);
CGContextClearRect(_context, placeholderRect);
CGContextDrawImage(_context, placeholderRect, image.CGImage);
UIGraphicsEndImageContext();
CGContextRestoreGState(_context);
How do i maintain my rect (non-flipped), while the image is flipped?
Thanks
Instead of using CGContextDrawImage use [image drawAtPoint:CGPointMake(0,0)];
The trick may lie in this UIImage method
+ (UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
Where orientation is one of these :)
typedef enum {
UIImageOrientationUp,
UIImageOrientationDown, // 180 deg rotation
UIImageOrientationLeft, // 90 deg CCW
UIImageOrientationRight, // 90 deg CW
UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip
UIImageOrientationDownMirrored, // horizontal flip
UIImageOrientationLeftMirrored, // vertical flip
UIImageOrientationRightMirrored, // vertical flip
} UIImageOrientation;
Edit: Update
I just did this simple code sample in a UIView subclass overriding drawrect and it worked perfectly. It doesn't use the UIImage method but works all the same.
UIImage *image = [UIImage imageNamed:#"image.png"];
CGContextRef _context = UIGraphicsGetCurrentContext();
CGContextSaveGState(_context);
CGContextDrawImage(_context, CGRectMake(100, 20, image.size.width, image.size.height), image.CGImage);
CGContextScaleCTM(_context, -1.0f, 1.0f);
CGContextDrawImage(_context, CGRectMake(-300, 20, image.size.width, image.size.height), image.CGImage);
CGContextRestoreGState(_context);
Related
I'm trying to change the color of an area of my UIImage with CGContext then create a new image from the current state. The original image has the correct orientation but after this, the image turns side ways.
CGRect imageRect = CGRectMake(0, 0, originalImage.size.width, originalImage.size.height);
UIGraphicsBeginImageContextWithOptions(originalImage.size, false, originalImage.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextDrawImage(context, imageRect, originalImage.CGImage);
CGContextSetRGBFillColor(context, 255.0f, 255.0f, 255.0f, 1.0f);
CGContextFillRect(context, CGRectMake(5,5,100,100));
CGContextRotateCTM (context, radians(270));
CGContextRestoreGState(context);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
It's a very easy question.
Because iOS system has 3 different Coordinate System.
UIKit - y axis direction is down
Core Graphics(Quartz) - y axis direction is up
OpenGL ES - y axis direction is up
The originalImage is create by UIKit and the target image is create by Core Graphics, so it should be upside-down.
If you want get the correct image, you can use:
UIImageView* imageV = [[UIImageView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
imageV.layer.borderColor = [UIColor redColor].CGColor;
imageV.layer.borderWidth = 1;
imageV.image = img;
imageV.layer.transform = CATransform3DRotate(imageV.layer.transform, M_PI, 1.0f, 0.0f, 0.0f);
[self.view addSubview:imageV];
Hope it can help you.
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)));
Iam applying transformations to the UIImageView(Rotate, scale and invert) and I want to save the UIImage from rotated UIImageView. So How can I get the exact bounding box of the UIImage to draw the UIImage View.
CGAffineTransform transform = selImageView.transform;
CGPathRef rotatedImageRectPath = CGPathCreateWithRect(selImageView.frame, &transform);
CGRect boundingBox = CGPathGetBoundingBox(rotatedImageRectPath);
CGSize rotatedSize = boundingBox.size;
UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 0.0f);
// Move the origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), rotatedSize.width/2, rotatedSize.height/2);
// CGContextSetFillColorWithColor(UIGraphicsGetCurrentContex(),[UIColor clearColor].CGColor);
//Rotate the image context using tranform
CGContextConcatCTM(UIGraphicsGetCurrentContext(), selImageView.transform);
// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(-aTransImage.size.width / 2, -aTransImage.size.height / 2, aTransImage.size.width, aTransImage.size.height), [aTransImage CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
Check out this app. It does most of the task you are trying to perform. you can analyze the code for working.
https://github.com/heitorfr/ios-image-editor
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.
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