How to Rotate a UIImage 90 degrees?
I believe the easiest way (and thread safe too) is to do:
//assume that the image is loaded in landscape mode from diskUIImage * landscapeImage = [UIImage imageNamed:imgname];UIImage * portraitImage = [[UIImage alloc] initWithCGImage: landscapeImage.CGImage scale: 1.0 orientation: UIImageOrientationRight];
Note: As Brainware said this only modifies the orientation data of the image - the pixel data is untouched. For some applications, this may not be enough.
Or in Swift:
guard let landscapeImage = UIImage(named: "imgname"), let landscapeCGImage = landscapeImage.cgImageelse { return }let portraitImage = UIImage(cgImage: landscapeCGImage, scale: landscapeImage.scale, orientation: .right)
Check out the simple and awesome code of Hardy Macia at: cutting-scaling-and-rotating-uiimages
Just call
UIImage *rotatedImage = [originalImage imageRotatedByDegrees:90.0];
Thanks Hardy Macia!
Header:
- (UIImage *)imageAtRect:(CGRect)rect;
- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize;
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
- (UIImage *)imageByScalingToSize:(CGSize)targetSize;
- (UIImage *)imageRotatedByRadians:(CGFloat)radians;
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
Since the link may die, here's the complete code
//// UIImage-Extensions.h//// Created by Hardy Macia on 7/1/09.// Copyright 2009 Catamount Software. All rights reserved.//#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@interface UIImage (CS_Extensions)- (UIImage *)imageAtRect:(CGRect)rect;- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize;- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;- (UIImage *)imageByScalingToSize:(CGSize)targetSize;- (UIImage *)imageRotatedByRadians:(CGFloat)radians;- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;@end;//// UIImage-Extensions.m//// Created by Hardy Macia on 7/1/09.// Copyright 2009 Catamount Software. All rights reserved.//#import "UIImage-Extensions.h"CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};@implementation UIImage (CS_Extensions)-(UIImage *)imageAtRect:(CGRect)rect{ CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect); UIImage* subImage = [UIImage imageWithCGImage: imageRef]; CGImageRelease(imageRef); return subImage;}- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize { UIImage *sourceImage = self; UIImage *newImage = nil; CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if (widthFactor > heightFactor) scaleFactor = widthFactor; else scaleFactor = heightFactor; scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor > heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; } else if (widthFactor < heightFactor) { thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } // this is actually the interesting part: UIGraphicsBeginImageContext(targetSize); CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); if(newImage == nil) NSLog(@"could not scale image"); return newImage ;}- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize { UIImage *sourceImage = self; UIImage *newImage = nil; CGSize imageSize = sourceImage.size; CGFloat width = imageSize.width; CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); if (CGSizeEqualToSize(imageSize, targetSize) == NO) { CGFloat widthFactor = targetWidth / width; CGFloat heightFactor = targetHeight / height; if (widthFactor < heightFactor) scaleFactor = widthFactor; else scaleFactor = heightFactor; scaledWidth = width * scaleFactor; scaledHeight = height * scaleFactor; // center the image if (widthFactor < heightFactor) { thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; } else if (widthFactor > heightFactor) { thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; } } // this is actually the interesting part: UIGraphicsBeginImageContext(targetSize); CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); if(newImage == nil) NSLog(@"could not scale image"); return newImage ;}- (UIImage *)imageByScalingToSize:(CGSize)targetSize { UIImage *sourceImage = self; UIImage *newImage = nil; // CGSize imageSize = sourceImage.size; // CGFloat width = imageSize.width; // CGFloat height = imageSize.height; CGFloat targetWidth = targetSize.width; CGFloat targetHeight = targetSize.height; // CGFloat scaleFactor = 0.0; CGFloat scaledWidth = targetWidth; CGFloat scaledHeight = targetHeight; CGPoint thumbnailPoint = CGPointMake(0.0,0.0); // this is actually the interesting part: UIGraphicsBeginImageContext(targetSize); CGRect thumbnailRect = CGRectZero; thumbnailRect.origin = thumbnailPoint; thumbnailRect.size.width = scaledWidth; thumbnailRect.size.height = scaledHeight; [sourceImage drawInRect:thumbnailRect]; newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); if(newImage == nil) NSLog(@"could not scale image"); return newImage ;}- (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; [rotatedViewBox release]; // 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;}@end;
What about something like:
static inline double radians (double degrees) {return degrees * M_PI/180;}UIImage* rotate(UIImage* src, UIImageOrientation orientation){ UIGraphicsBeginImageContext(src.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orientation == UIImageOrientationRight) { CGContextRotateCTM (context, radians(90)); } else if (orientation == UIImageOrientationLeft) { CGContextRotateCTM (context, radians(-90)); } else if (orientation == UIImageOrientationDown) { // NOTHING } else if (orientation == UIImageOrientationUp) { CGContextRotateCTM (context, radians(90)); } [src drawAtPoint:CGPointMake(0, 0)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image;}