iosswiftanimationuiviewuiviewanimation

How to rotate image in Swift?


I am unable to rotate the image by 90 degrees in swift. I have written below code but there is an error and doesn't compile

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

    //Calculate the size of the rotated view's containing box for our drawing space
    let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
    let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI / 180))
    rotatedViewBox.transform = t
    let rotatedSize: CGSize = rotatedViewBox.frame.size

    //Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize)
    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: rotatedSize.width / 2, y: rotatedSize.height / 2)

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

    //Now, draw the rotated/scaled image into the context
    bitmap.scaleBy(x: 1.0, y: -1.0)
    bitmap.draw(oldImage, in:  CGRect(origin: (x: -oldImage.size.width / 2,  y: -oldImage.size.height / 2, width:  oldImage.size.width, height: oldImage.size.height), size: oldImage.cgImage))

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

    return newImage

  }

below is the code i am not sure about

bitmap.draw(oldImage, in:  CGRect(origin: (x: -oldImage.size.width / 2,  y: -oldImage.size.height / 2, width:  oldImage.size.width, height: oldImage.size.height), size: oldImage.cgImage))

Solution

  • This is an extension of UIImage that targets Swift 4.0 and can rotate just the image without the need for a UIImageView. Tested successfully that the image was rotated, and not just had its exif data changed.

    import UIKit
    
    extension UIImage {
        func rotate(radians: CGFloat) -> UIImage {
            let rotatedSize = CGRect(origin: .zero, size: size)
                .applying(CGAffineTransform(rotationAngle: CGFloat(radians)))
                .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: radians)
                draw(in: CGRect(x: -origin.y, y: -origin.x,
                                width: size.width, height: size.height))
                let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
    
                return rotatedImage ?? self
            }
    
            return self
        }
    }
    

    To perform a 180 degree rotation, you can call it like this:

    let rotatedImage = image.rotate(radians: .pi)
    

    If for whatever reason it fails to rotate, the original image will then be returned.