After I load an image from the device, I need to rotate it 37.8 degrees then display it on a View.
Is there an function in Objective-C that can do the image rotation?
Ian
To rotate the view:
imageView.transform = CGAffineTransformMakeRotation(37.8°);
To rotate the image,
Calculate the width and height will be occupied by the image after rotation.
Create a CGContext by UIGraphicsBeginImageContext.
CGContextRotateCTM(UIGraphicsGetCurrentContext(), 37.8°);
[yourImage drawAtPoint:...];
UIGraphicsGetImageFromCurrentImageContext(); and use this image instead.
Release the context.
Yes, see my answer to this question: Question about rotating a slider
To convert degrees to radians (for the positionInRadians arg) use this function:
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
To rotate the image, try this:
-(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);
}
This method allows you to rotate an image an arbitrary amount:
- (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;
}
See this link for more information.
Related
I am using this code to rotate UIImage.
CGFloat DegreesToRads(CGFloat degrees) {
return degrees * M_PI / 180;
}
- (UIImage *)scaleAndRotateImage:(UIImage *)image forAngle: (double) angle {
float radians=DegreesToRads(angle);
// calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0, image.size.width, image.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(radians);
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, radians);
// Now, draw the rotated/scaled image into the context
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;
}
Works ok, but the quality of image is worse after rotation. What could be the cause?
try
UIGraphicsBeginImageContextWithOptions(rotatedSize, NO, 2.0)
from apple documentation:
void UIGraphicsBeginImageContextWithOptions(
CGSize size,
BOOL opaque,
CGFloat scale
);
Parameters
size The size (measured in points) of the new bitmap context. This represents the size of the image returned by the UIGraphicsGetImageFromCurrentImageContext function. To get the size of the bitmap in pixels, you must multiply the width and height values by the value in the scale parameter.
opaque
A Boolean flag indicating whether the bitmap is opaque. If you know the bitmap is fully opaque, specify YES to ignore the alpha channel and optimize the bitmap’s storage. Specifying NO means that the bitmap must include an alpha channel to handle any partially transparent pixels.
scale
The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
bye :)
I have the exact problem as described here:
crop a rotated UIImage.
I need to crop a rotated UIImage, however, when I try the solution it doesn't crop the image
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:videoPreviewView.frame];
NSLog(#"frame width: %f height:%f x:%f y:%f",videoPreviewView.frame.size.width, videoPreviewView.frame.size.height,videoPreviewView.frame.origin.x,videoPreviewView.frame.origin.y);
rotatedViewBox.transform = CGAffineTransformMakeRotation(90 * M_PI / 180);
CGSize rotatedSize = rotatedViewBox.frame.size;
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
CGContextRotateCTM(bitmap, 90 * M_PI / 180);
CGContextScaleCTM(bitmap, 1.0f, -1.0f);
CGContextDrawImage(bitmap, CGRectMake(-videoPreviewView.frame.size.width / 2.0f,
-videoPreviewView.frame.size.height / 2.0f,
videoPreviewView.frame.size.width,
videoPreviewView.frame.size.height),
image.CGImage);
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The log is:
frame width:310 height:310 x:0 y: 69
The rotation works though but the new image is not cropped on 0,69,310,310 of the old image.
You are using a "solution" which, although accepted, also carries the OP comment "but it's not working."
The solution only claims to deal with the rotation part of the problem, not the crop. It's doing what it claims to do, but no more.
Here's a CG function that performs a crop:
CGImageRef CGImageCreateWithImageInRect (
CGImageRef image,
CGRect rect
);
Input you image and the rect of the region you want to crop to.
See the answer here for an example use:
Cropping an UIImage
This is a simple issue, which is bugging me ...
So, I have an object of UIImageView over which, I use
-(void)rotate {
// ...
CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180));
self.image.transform = transform; // image is a property.
}
So, when I call this method once, it rotates the object !. When I call the method again, I expect the object to be rotated again - but it is not rotating by another 180 degrees. After messing with the coordinates and moving the image, I can understand that the -perspective of the object has also be rotated by 180 degrees and all coordinates have been inverted as well.
I want the object's perspective to be restored (although it's been rotated by some angle) such that, I can continue to rotate and move it just like before !
Any ideas ?
Anyways, this code works:
UIImage* rotateUIImage(const UIImage* src, float angleDegrees) {
UIView* rotatedViewBox = [[UIView alloc] initWithFrame: CGRectMake(0, 0, src.size.width, src.size.height)];
float angleRadians = angleDegrees * ((float)M_PI / 180.0f);
CGAffineTransform t = CGAffineTransformMakeRotation(angleRadians);
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
CGContextRotateCTM(bitmap, angleRadians);
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-src.size.width / 2, -src.size.height / 2, src.size.width, src.size.height), [src CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Solved the problem with CABasicAnimation !
I have to rotate a UIImage before I save it out to file. I've tried a number of methods, some of which seem to work for other people, but all it seems to do it turn my image solid white. Here's my code:
CGFloat radians = 90.0f * M_PI/180;
UIGraphicsBeginImageContext(image.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextConcatCTM(ctx, CGAffineTransformMakeRotation(radians));
CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Can anyone spot what I'm doing wrong? The variable "image" is a UIImage.
- (UIImage *)imageRotatedByRadians:(CGFloat)radians
{
// 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(radians);
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, radians);
// 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;
}
I believe you are not taking into account that the coordinate system for iPhone and Quartz Coordinate system are different.
try putting these two lines before CGContextConcatCTM.
// to account for Quartz coordinate system.
CGContextScaleCTM(cx, 1, -1);
CGContextTranslateCTM(ctx, 0, -longerSide); // width or height depending on the orientation
I suggest to put your image in UIImageView and then use following code:
- (void)setupRotatingButtons
{
// call this method once; make sure "self.view" is not nil or the button
// won't appear. the below variables are needed in the #interface.
// center: the center of rotation
// radius: the radius
// time: a CGFloat that determines where in the cycle the button is located at
// (note: it will keep increasing indefinitely; you need to use
// modulus to find a meaningful value for the current position, if
// needed)
// speed: the speed of the rotation, where 2 * 3.1415 is **roughly** 1 lap a
// second
center = CGPointMake(240, 160);
radius = 110;
time = 0;
speed = .3 * 3.1415; // <-- will rotate CW 360 degrees per .3 SECOND (1 "lap"/s)
CADisplayLink *dl = [CADisplayLink displayLinkWithTarget:self selector:#selector(continueCircling:)];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)continueCircling:(CADisplayLink *)dl
{
time += speed * dl.duration;
//here rotate your image view
yourImageView.transform = CGAffineTransformMakeRotation(time);
}
Use following code to rotate:
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"image1.png"]];
[imageView setFrame:CGRectMake(0.0f, 0.0f,100.0f, 100.0f)];
[self.view addSubview:imageView];
self.imageView.transform = CGAffineTransformMakeRotation((90.0f * M_PI) / 180.0f);
I want to rotate an UIImage (not UIImageView) in custom degree
I followed this post but it didn't work for me.
Anyone can help? Thanks.
UPDATE:
The code below does some of the job, but I lose some of the image after rotating it:
What should I change to get it right? (btw the yellow color in the screenshots is my UIImageView bg)
- (UIImage *) rotate: (UIImage *) image
{
double angle = 20;
CGSize s = {image.size.width, image.size.height};
UIGraphicsBeginImageContext(s);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, 0,image.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextRotateCTM(ctx, 2*M_PI*angle/360);
CGContextDrawImage(ctx,CGRectMake(0,0,image.size.width, image.size.height),image.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
This method return you image on your angle of rotate
#pragma mark -
#pragma mark Rotate Image
- (UIImage *)scaleAndRotateImage:(UIImage *)image {
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
CGFloat boundHeight;
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0); //use angle/360 *MPI
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
}
- (UIImage *)rotate:(UIImage *)image radians:(float)rads
{
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, rads);
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;
}
this function rotates any image on its center, but the image becomes a square so I would suggest referencing the image center when drawing it after this function.
You need to address two things to make this work.
You are rotating about the bottom corner of the image instead of the centre
The bounding rectangle of the resulting image needs to be larger now the image is rotated for it to fit in.
To solve the rotation about the centre, first perform a translate to the centre, then rotate, then translate back.
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);
// Draw the image into the context
CGContextDrawImage(context, CGRectMake(-imageView.image.size.width/2, -imageView.image.size.height/2, imageView.image.size.width, imageView.image.size.height), imageView.image.CGImage);
// Get an image from the context
rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];
To calculate the size of the bounding rectangle you'd need to fit the new rotated image into use this:
- (CGRect) getBoundingRectAfterRotation: (CGRect) rectangle byAngle: (CGFloat) angleOfRotation {
// Calculate the width and height of the bounding rectangle using basic trig
CGFloat newWidth = rectangle.size.width * fabs(cosf(angleOfRotation)) + rectangle.size.height * fabs(sinf(angleOfRotation));
CGFloat newHeight = rectangle.size.height * fabs(cosf(angleOfRotation)) + rectangle.size.width * fabs(sinf(angleOfRotation));
// Calculate the position of the origin
CGFloat newX = rectangle.origin.x + ((rectangle.size.width - newWidth) / 2);
CGFloat newY = rectangle.origin.y + ((rectangle.size.height - newHeight) / 2);
// Return the rectangle
return CGRectMake(newX, newY, newWidth, newHeight);
}
You can find these techniques in my previous posts and answers here:
Creating a UIImage from a rotated UIImageView
and here:
Saving 2 UIImages
Hope this helps,
Dave
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
You have to do some thing like this
YourContainer.transform = CGAffineTransformMakeRotation( 270.0/180*M_PI );
I think rest of the thing you can figured out..