How to Rotate a UIImage 90 degrees?

前端 未结 19 845
天涯浪人
天涯浪人 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 09:00

    I like the simple elegance of Peter Sarnowski's answer, but it can cause problems when you can't rely on EXIF metadata and the like. In situations where you need to rotate the actual image data I would recommend something like this:

    - (UIImage *)rotateImage:(UIImage *) img
    {
        CGSize imgSize = [img size];
        UIGraphicsBeginImageContext(imgSize);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextRotateCTM(context, M_PI_2);
        CGContextTranslateCTM(context, 0, -640);
        [img drawInRect:CGRectMake(0, 0, imgSize.height, imgSize.width)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    

    The above code takes an image whose orientation is Landscape (can't remember if it's Landscape Left or Landscape Right) and rotates it into Portrait. It is an example which can be modified for your needs.

    The key arguments you would have to play with are CGContextRotateCTM(context, M_PI_2) where you decide how much you want to rotate by, but then you have to make sure the picture still draws on the screen using CGContextTranslateCTM(context, 0, -640). This last part is quite important to make sure you see the image and not a blank screen.

    For more info check out the source.

    0 讨论(0)
  • 2020-11-22 09:00

    resize-a-uiimage-the-right-way explains some of the issues many code samples for doing this have, and has some code snippets to help deal with UIImages - the private helper method in UIImage+resize.m accepts a transform to allow rotation, so you'd just need to expose that as a public interface.

    // Returns a copy of the image that has been transformed using the given affine transform and scaled to the new size
    // The new image's orientation will be UIImageOrientationUp, regardless of the current image's orientation
    // If the new size is not integral, it will be rounded up
    - (UIImage *)resizedImage:(CGSize)newSize
                    transform:(CGAffineTransform)transform
               drawTransposed:(BOOL)transpose
         interpolationQuality:(CGInterpolationQuality)quality {
        CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
        CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
        CGImageRef imageRef = self.CGImage;
    
        // Build a context that's the same dimensions as the new size
        CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                                    newRect.size.width,
                                                    newRect.size.height,
                                                    CGImageGetBitsPerComponent(imageRef),
                                                    0,
                                                    CGImageGetColorSpace(imageRef),
                                                    CGImageGetBitmapInfo(imageRef));
    
        // Rotate and/or flip the image if required by its orientation
        CGContextConcatCTM(bitmap, transform);
    
        // Set the quality level to use when rescaling
        CGContextSetInterpolationQuality(bitmap, quality);
    
        // Draw into the context; this scales the image
        CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
    
        // Get the resized image from the context and a UIImage
        CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
        UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    
        // Clean up
        CGContextRelease(bitmap);
        CGImageRelease(newImageRef);
    
        return newImage;
    }
    

    This is the license from that file:

    // Created by Trevor Harmon on 8/5/09.
    // Free for personal or commercial use, with or without modification.
    // No warranty is expressed or implied.
    
    0 讨论(0)
  • 2020-11-22 09:01

    As strange as this seems, the following code solved the problem for me:

    + (UIImage*)unrotateImage:(UIImage*)image {
        CGSize size = image.size;
        UIGraphicsBeginImageContext(size);
        [image drawInRect:CGRectMake(0,0,size.width ,size.height)];
        UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    
    0 讨论(0)
  • 2020-11-22 09:02

    There is a extremely efficient UIImage category named NYXImagesKit. It uses vDSP, CoreImage and vImage to be as fast as possible. It has a UIImage+Rotating category that saved my day :)

    https://github.com/Nyx0uf/NYXImagesKit

    0 讨论(0)
  • 2020-11-22 09:03

    Simple. Just change the image orientation flag.

    UIImage *oldImage = [UIImage imageNamed:@"whatever.jpg"];
    UIImageOrientation newOrientation;
    switch (oldImage.imageOrientation) {
        case UIImageOrientationUp:
            newOrientation = UIImageOrientationLandscapeLeft;
            break;
        case UIImageOrientationLandscapeLeft:
            newOrientation = UIImageOrientationDown;
            break;
        case UIImageOrientationDown:
            newOrientation = UIImageOrientationLandscapeRight;
            break;
        case UIImageOrientationLandscapeRight:
            newOrientation = UIImageOrientationUp;
            break;
        // you can also handle mirrored orientations similarly ...
    }
    UIImage *rotatedImage = [UIImage imageWithCGImage:oldImage.CGImage scale:1.0f orientation:newOrientation];
    
    0 讨论(0)
  • 2020-11-22 09:05

    Minor change to the other answers that are based on Hardy Macia's code. There is no need to create a whole UIView object simply to calculate the bounding rectangle of the rotated image. Just apply a rotate transform to the image rectangle using CGRectApplyAffineTransform.

    static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
    static CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;}
    
    
    - (CGSize)rotatedImageSize:(CGFloat)degrees
    {
        CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
        CGRect originalImageRect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGRect rotatedImageRect = CGRectApplyAffineTransform(originalImageRect, t);
        CGSize rotatedSize = rotatedImageRect.size;
    
        return rotatedSize;
    }
    
    - (UIImage*)imageRotatedByDegrees:(CGFloat)degrees
    {
        // calculate the size of the rotated view's containing box for our drawing space
        CGSize rotatedSize = [self rotatedImageSize:degrees];
    
        // 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;
    }
    
    0 讨论(0)
提交回复
热议问题