How to Rotate a UIImage 90 degrees?

前端 未结 19 872
天涯浪人
天涯浪人 2020-11-22 08:45

I have a UIImage that is UIImageOrientationUp (portrait) that I would like to rotate counter-clockwise by 90 degrees (to landscape). I don\'t want

相关标签:
19条回答
  • 2020-11-22 08:51

    For Swift: Here is a simple extension to UIImage:

    //ImageRotation.swift
    
    import UIKit
    
    extension UIImage {  
        public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {
            let radiansToDegrees: (CGFloat) -> CGFloat = {
                return $0 * (180.0 / CGFloat(M_PI))
            }
            let degreesToRadians: (CGFloat) -> CGFloat = {
                return $0 / 180.0 * CGFloat(M_PI)
            }
    
            // calculate the size of the rotated view's containing box for our drawing space
            let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: size))
            let t = CGAffineTransformMakeRotation(degreesToRadians(degrees));
            rotatedViewBox.transform = t
            let rotatedSize = rotatedViewBox.frame.size
    
            // Create the bitmap context
            UIGraphicsBeginImageContext(rotatedSize)
            let 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.0, rotatedSize.height / 2.0);
    
            //   // Rotate the image context
            CGContextRotateCTM(bitmap, degreesToRadians(degrees));
    
            // Now, draw the rotated/scaled image into the context
            var yFlip: CGFloat
    
            if(flip){
                yFlip = CGFloat(-1.0)
            } else {
                yFlip = CGFloat(1.0)
            }
    
            CGContextScaleCTM(bitmap, yFlip, -1.0)
            CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return newImage
        }
    }
    

    (Source)

    Use it with:

    rotatedPhoto = rotatedPhoto?.imageRotatedByDegrees(90, flip: false) 
    

    The former will rotate an image and flip it if flip is set to true.

    0 讨论(0)
  • 2020-11-22 08:54

    Rotate Image by 90 degree (clockwise/anti-clockwise direction)

    Function call -

     UIImage *rotatedImage = [self rotateImage:originalImage clockwise:YES];
    

    Implementation:

    - (UIImage*)rotateImage:(UIImage*)sourceImage clockwise:(BOOL)clockwise
      {
        CGSize size = sourceImage.size;
        UIGraphicsBeginImageContext(CGSizeMake(size.height, size.width));
        [[UIImage imageWithCGImage:[sourceImage CGImage]
                             scale:1.0
                       orientation:clockwise ? UIImageOrientationRight : UIImageOrientationLeft]
                       drawInRect:CGRectMake(0,0,size.height ,size.width)];
    
       UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
    
       return newImage;
      }
    
    0 讨论(0)
  • 2020-11-22 08:55

    Swift 4.2 version of RawMean's answer:

    extension UIImage {
    
    func rotated(byDegrees degree: Double) -> UIImage {
        let radians = CGFloat(degree * .pi) / 180.0 as CGFloat
        let rotatedSize = self.size
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
        let bitmap = UIGraphicsGetCurrentContext()
        bitmap?.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
        bitmap?.rotate(by: radians)
        bitmap?.scaleBy(x: 1.0, y: -1.0)
        bitmap?.draw(
            self.cgImage!,
            in: CGRect.init(x: -self.size.width / 2, y: -self.size.height / 2 , width: self.size.width, height: self.size.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext() // this is needed
        return newImage!
    }
    
    }
    
    0 讨论(0)
  • 2020-11-22 08:57

    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;
    
    0 讨论(0)
  • 2020-11-22 08:58

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 08:59

    Here is a Swift extension to UIImage that rotates the image by any arbitrary angle. Use it like this: let rotatedImage = image.rotated(byDegrees: degree). I used the Objective-C code in one of the other answers and removed a few lines that we incorrect (rotated box stuff) and turned it into an extension for UIImage.

    extension UIImage {
    
    func rotate(byDegrees degree: Double) -> UIImage {
        let radians = CGFloat(degree*M_PI)/180.0 as CGFloat
        let rotatedSize = self.size
        let scale = UIScreen.mainScreen().scale
        UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
        let 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 );
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
    
        return newImage
    }
    }
    
    0 讨论(0)
提交回复
热议问题