Created
June 7, 2016 03:19
-
-
Save rosslebeau/f49197e4176f9ae5dff9e193e5e88eb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension CGSize { | |
func scaled(byFactor factor: CGFloat) -> CGSize { | |
return CGSize(width: width * factor, | |
height: height * factor) | |
} | |
} | |
extension CGSize { | |
func scaled(toSize: CGSize, mode: UIImage.ScaleMode) -> CGSize { | |
let (widthFactor, heightFactor) = (toSize.width / width, toSize.height / height) | |
let scaleFactor: CGFloat | |
switch mode { | |
case .aspectFit: | |
scaleFactor = min(widthFactor, heightFactor) | |
case .aspectFill: | |
scaleFactor = max(widthFactor, heightFactor) | |
} | |
return scaled(byFactor: scaleFactor) | |
} | |
} | |
extension CGRect { | |
struct Anchor { | |
let vertical: Vertical | |
let horizontal: Horizontal | |
enum Horizontal { | |
case left | |
case center | |
case right | |
} | |
enum Vertical { | |
case top | |
case center | |
case bottom | |
} | |
} | |
// Initializes a CGRect with an origin such that it is "anchored" | |
// inside a rect with size `containerSize` | |
init(size: CGSize, anchor: Anchor, containerSize: CGSize) { | |
let originX: CGFloat | |
let originY: CGFloat | |
switch anchor.vertical { | |
case .top: | |
originY = 0 | |
case .center: | |
originY = (containerSize.height - size.height) / 2 | |
case .bottom: | |
originY = containerSize.height - size.height | |
} | |
switch anchor.horizontal { | |
case .left: | |
originX = 0 | |
case .center: | |
originX = (containerSize.width - size.width) / 2 | |
case .right: | |
originX = containerSize.width - size.width | |
} | |
self.origin = CGPoint(x: originX, y: originY) | |
self.size = size | |
} | |
} | |
extension UIImage { | |
enum ScaleMode { | |
case aspectFit | |
case aspectFill | |
} | |
func cropped( | |
toSize: CGSize, | |
croppingAnchor: CGRect.Anchor = CGRect.Anchor(vertical: .center, horizontal: .center) | |
) -> UIImage { | |
let requiresResizing = !size.equalTo(toSize) | |
guard requiresResizing else { | |
return self | |
} | |
let drawingRect = CGRect(size: size, anchor: croppingAnchor, containerSize: toSize) | |
let scaledImage: UIImage | |
UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0) | |
draw(in: drawingRect) | |
scaledImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return scaledImage | |
} | |
func scaled( | |
toSize: CGSize, | |
mode: ScaleMode, | |
croppingAnchor: CGRect.Anchor = CGRect.Anchor(vertical: .center, horizontal: .center) | |
) -> UIImage { | |
let requiresResizing = !size.equalTo(toSize) | |
guard requiresResizing else { | |
return self | |
} | |
let drawingSize = size.scaled(toSize: toSize, mode: mode) | |
let drawingRect = CGRect(size: drawingSize, anchor: croppingAnchor, containerSize: toSize) | |
let scaledImage: UIImage | |
UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0) | |
draw(in: drawingRect) | |
scaledImage = UIGraphicsGetImageFromCurrentImageContext() | |
UIGraphicsEndImageContext() | |
return scaledImage | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment