Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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