Skip to content

Instantly share code, notes, and snippets.

@fnk0
Created October 13, 2015 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fnk0/2e108700bdbe4a92766c to your computer and use it in GitHub Desktop.
Save fnk0/2e108700bdbe4a92766c to your computer and use it in GitHub Desktop.
Simple UIImage Extension to allow a image to scale and rotate based on Orientantion
import Foundation
import UIKit
extension UIImage {
func scaleAndRotateImage(maxSize: CGFloat) -> UIImage {
let imgRef = self.CGImage
let width = CGFloat(CGImageGetWidth(imgRef))
let height = CGFloat(CGImageGetHeight(imgRef))
var transform = CGAffineTransformIdentity
var bounds = CGRectMake(0, 0, width, height)
if width > maxSize || height < maxSize {
let ratio = width / height
if ratio > 1 {
bounds.size.width = maxSize
bounds.size.height = bounds.size.width / ratio
} else {
bounds.size.height = maxSize
bounds.size.width = bounds.size.height * ratio
}
}
let scaleRatio = bounds.size.width / width
let imageSize = CGSizeMake(width, height)
var boundHeight : CGFloat = 0.0
let ori = self.imageOrientation
switch(ori) {
case .Up:
transform = CGAffineTransformIdentity
break
case .Down:
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
break
case .Left:
boundHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = boundHeight
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width)
transform = CGAffineTransformRotate(transform, CGFloat(3.0 * M_PI / 2.0))
break
case .Right:
boundHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = boundHeight
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI / 2.0))
break
case .UpMirrored:
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0)
transform = CGAffineTransformScale(transform, -1.0, -1.0)
break
case .DownMirrored:
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height)
transform = CGAffineTransformScale(transform, 1.0, -1.0)
break
case .LeftMirrored:
boundHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = boundHeight
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width)
transform = CGAffineTransformScale(transform, -1.0, 1.0)
transform = CGAffineTransformRotate(transform, CGFloat(3.0 * M_PI / 2.0))
break
case .RightMirrored:
boundHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = boundHeight
transform = CGAffineTransformMakeScale(-1.0, 1.0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI / 2.0))
break
}
UIGraphicsBeginImageContext(bounds.size)
let context = UIGraphicsGetCurrentContext()
if ori == UIImageOrientation.Right || ori == UIImageOrientation.Left {
CGContextScaleCTM(context, -scaleRatio, scaleRatio)
CGContextTranslateCTM(context, -height, 0.0)
} else {
CGContextScaleCTM(context, scaleRatio, -scaleRatio)
CGContextTranslateCTM(context, 0.0, -height)
}
CGContextConcatCTM(context, transform)
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
@akotulu
Copy link

akotulu commented Apr 13, 2017

Swift 3 version

func scaleAndRotateImage(maxSize: CGFloat) -> UIImage
{
    guard let imgRef = self.cgImage
        else { return self }
    
    let width = CGFloat(imgRef.width)
    let height = CGFloat(imgRef.height)
    
    var transform: CGAffineTransform = .identity
    
    var bounds = CGRect(x: 0, y: 0, width: width, height: height)
    
    if width > maxSize || height < maxSize {
        let ratio = width / height
        
        if ratio > 1 {
            bounds.size.width = maxSize
            bounds.size.height = bounds.size.width / ratio
        } else {
            bounds.size.height = maxSize
            bounds.size.width = bounds.size.height * ratio
        }
    }
    
    let scaleRatio = bounds.size.width / width
    let imageSize = CGSize(width: width, height: height)
    var boundHeight : CGFloat = 0.0
    
    let ori = self.imageOrientation
    
    switch(ori) {
    case .up:
        transform = .identity
        break
        
    case .down:
        transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height)
        transform = transform.rotated(by: CGFloat(Double.pi))
        break
        
    case .left:
        boundHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = boundHeight
        transform = CGAffineTransform(translationX: 0.0, y: imageSize.width)
        transform = transform.rotated(by: CGFloat(3.0 * Double.pi / 2.0))
        break
        
    case .right:
        boundHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = boundHeight
        transform = CGAffineTransform(translationX: imageSize.height, y: 0.0)
        transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
        break
        
    case .upMirrored:
        transform = CGAffineTransform(translationX: imageSize.width, y: 0.0)
        transform = transform.scaledBy(x: -1.0, y: -1.0)
        break
        
    case .downMirrored:
        transform = CGAffineTransform(translationX: 0.0, y: imageSize.height)
        transform = transform.scaledBy(x: 1.0, y: -1.0)
        break
        
    case .leftMirrored:
        boundHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = boundHeight
        transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width)
        transform = transform.scaledBy(x: -1.0, y: 1.0)
        transform = transform.rotated(by: CGFloat(3.0 * Double.pi / 2.0))
        break
        
    case .rightMirrored:
        boundHeight = bounds.size.height
        bounds.size.height = bounds.size.width
        bounds.size.width = boundHeight
        transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        transform = transform.rotated(by: CGFloat(Double.pi / 2.0))
        break
    }
    
    UIGraphicsBeginImageContext(bounds.size)
    
    guard let context = UIGraphicsGetCurrentContext()
        else { return self }
    
    if ori == UIImageOrientation.right || ori == UIImageOrientation.left {
        context.scaleBy(x: -scaleRatio, y: scaleRatio)
        context.translateBy(x: -height, y: 0.0)
    } else {
        context.scaleBy(x: scaleRatio, y: -scaleRatio)
        context.translateBy(x: 0.0, y: -height)
    }
    
    context.concatenate(transform)
    context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
    
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return image ?? self
}   

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment