Created
May 31, 2016 19:09
-
-
Save oleksii-demedetskyi/c22346fea08168c9d994771b580c0654 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
//: Playground - noun: a place where people can play | |
import UIKit | |
// credit: http://stackoverflow.com/questions/603907/uiimage-resize-then-crop#605385 | |
/// Cropping is a basic and generic operation on top of UIKit, | |
/// it deserves to be moved to some extension. No need to test it. | |
extension UIImage { | |
func cropToFrame(frame: CGRect) -> UIImage { | |
// Why use `UIGraphicsBeginImageContextWithOptions` over `UIGraphicsBeginImageContext`? | |
// see: http://stackoverflow.com/questions/4334233/how-to-capture-uiview-to-uiimage-without-loss-of-quality-on-retina-display#4334902 | |
UIGraphicsBeginImageContextWithOptions(size, false, 0.0) | |
self.drawInRect(frame) | |
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()! | |
UIGraphicsEndImageContext() | |
return scaledImage | |
} | |
} | |
/// This is main logic of our code. Pure function. Testable. Only lets. :) | |
func scaleAndCropRect(from source: CGSize, to target:CGSize) -> CGRect { | |
let widthFactor = target.width / source.width | |
let heightFactor = target.height / source.height | |
let scaled: CGSize; do { | |
let scaleFactor = max(heightFactor, widthFactor) | |
scaled = CGSize( | |
width: source.width * scaleFactor, | |
height: source.height * scaleFactor) | |
} | |
let origin: CGPoint; do { | |
if widthFactor > heightFactor { | |
origin = CGPoint(x: 0, y: (target.height - scaled.height) / 2.0) | |
} | |
else if widthFactor < heightFactor { | |
origin = CGPoint(x: (target.width - scaled.width) / 2.0, y: 0) | |
} else { | |
origin = CGPoint.zero | |
} | |
} | |
return CGRect(origin: origin, size: scaled) | |
} | |
/// Glue code to support old callsites. No need to test it. | |
func scaleAndCropImage(image:UIImage, toSize size: CGSize) -> UIImage { | |
// Sanity check; make sure the image isn't already sized. | |
guard image.size != size else { return image } | |
return image.cropToFrame(scaleAndCropRect(from: image.size, to: size)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment