How to rotate an image 90 degrees on iOS?

Viewed 91272

What I want to do is take a snapshot from my camera , send it to a server and then the server sends me back the image on a viewController. If the image is in portrait mode the image appears well on screen , however if the image was taken in landscape mode the image appears streched on the screen(as it tries to appear on portrait mode!). I dont know how to fix this but i guess one solution is first to check if the image is in portrait/landscape mode and then if it is on landscape mode rotate it by 90degrees before showing it on screen. So how could i do that?

14 Answers

Swift 4 | Xcode 9 syntax (please note that this code rotates a UIImageView 90 degrees clockwise, not a UIImage):

myImageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2))
 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {

    let size = oldImage.size
    UIGraphicsBeginImageContext(size)

    let bitmap: CGContext = UIGraphicsGetCurrentContext()!
    //Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: size.width / 2, y: size.height / 2)
    //Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat(Double.pi / 180)))
    //Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)

    let origin = CGPoint(x: -size.width / 2, y: -size.width / 2)

    bitmap.draw(oldImage.cgImage!, in: CGRect(origin: origin, size: size))

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage

}

Use of function

imageRotatedByDegrees(oldImage: yourImage, deg: degree) 

Doing it in the Image Level, in Swift 5:

extension UIImage{
    
    
    func imageRotated(by radian: CGFloat) -> UIImage{
        
        let rotatedSize = CGRect(origin: .zero, size: size)
            .applying(CGAffineTransform(rotationAngle: radian))
            .integral.size
        UIGraphicsBeginImageContext(rotatedSize)
        if let context = UIGraphicsGetCurrentContext() {
            let origin = CGPoint(x: rotatedSize.width / 2.0,
                                 y: rotatedSize.height / 2.0)
            context.translateBy(x: origin.x, y: origin.y)
            context.rotate(by: radian)
            draw(in: CGRect(x: -origin.y, y: -origin.x,
                            width: size.width, height: size.height))
            let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return rotatedImage ?? self
        }

        return self

    }
}

It´s best only use the bitmap. In my case use a UIImage that is in reference.image and I converted image at base64String. Without CGAffineTransformMakeRotation and without rotatedViewBox.transform

var rotatedSize = reference.image.size;
                //Create bitmap context
                UIGraphicsBeginImageContext(rotatedSize);
                var bitmap = UIGraphicsGetCurrentContext();
                //move origin to the middle of the image for rotation
                CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2);
                //rotate image context
                CGContextRotateCTM(bitmap, 1.5708);
                CGContextDrawImage(bitmap, CGRectMake(-reference.image.size.width / 2, -reference.image.size.height / 2, reference.image.size.width, reference.image.size.height), reference.image.CGImage);
                var rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
                var base64Image = UIImageJPEGRepresentation(rotatedImage, compression).base64EncodedStringWithOptions(0);
                UIGraphicsEndImageContext();
                return base64Image;

If you are looking to save image then you need to rotate picture context not the view. I have used provided examples above but they did not work well when centering the image. So I have enhanced and fixed as follows :

func imageRotatedByDegrees(deg degrees: CGFloat) -> UIImage {

    UIGraphicsBeginImageContext(CGSize(width: self.size.height, height: self.size.width))

    let bitmap: CGContext = UIGraphicsGetCurrentContext()!

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    bitmap.translateBy(x: self.size.width / 2, y: self.size.height / 2)

    // Rotate the image context
    bitmap.rotate(by: (degrees * CGFloat(Double.pi / 180)))

    // Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)

    let origin = CGPoint(x: -self.size.height / 2, y: -self.size.width / 2)

    bitmap.draw(self.cgImage!, in: CGRect(origin: origin, size: CGSize(width: self.size.width, height: self.size.height)))

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!

    UIGraphicsEndImageContext()

    return newImage
}
Related