Skip to content

Instantly share code, notes, and snippets.

@erica
Created May 31, 2016 15:31
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/157e20ea0c7e9f28a03a8b12448c8fd0 to your computer and use it in GitHub Desktop.
Save erica/157e20ea0c7e9f28a03a8b12448c8fd0 to your computer and use it in GitHub Desktop.
import UIKit
// Swift rewrite challenge
// Starting point: https://gist.github.com/jkereako/200342b66b5416fd715a#file-scale-and-crop-image-swift
func scaleAndCropImage(
image: UIImage,
toSize size: CGSize,
fitImage: Bool = true
) -> UIImage {
// Return original when cropping is not needed
guard !CGSizeEqualToSize(image.size, size) else { return image }
// Calculate scale factor for fit or fill
let (widthFactor, heightFactor) = (size.width / image.size.width, size.height / image.size.height)
let fitFillTest = fitImage ? widthFactor < heightFactor : widthFactor > heightFactor
let scaleFactor = fitFillTest ? widthFactor : heightFactor
// Establish drawing destination, which may start outside the drawing context bounds
let (scaledWidth, scaledHeight) = (image.size.width * scaleFactor, image.size.height * scaleFactor)
let drawingOrigin = CGPoint(
x: (size.width - scaledWidth) / 2.0,
y: (size.height - scaledHeight) / 2.0)
// Perform drawing and return image
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
let scaledImage: UIImage
do {
// Fill background
UIColor.blackColor().setFill(); UIRectFill(CGRect(origin: .zero, size: size))
// Draw scaled image
let drawingRect: CGRect = CGRect(
origin: drawingOrigin,
size: CGSize(width: scaledWidth, height: scaledHeight))
image.drawInRect(drawingRect)
// Fetch image
scaledImage = UIGraphicsGetImageFromCurrentImageContext()!
}
UIGraphicsEndImageContext()
return scaledImage
}
// Test with some basic placeholder data
guard let url = NSURL(string: "http://placehold.it/300x150") else { fatalError("Bad URL") }
guard let data = NSData(contentsOfURL: url) else { fatalError("Bad data") }
guard let img = UIImage(data: data) else { fatalError("Bad data") }
let outImageFit = scaleAndCropImage(img, toSize: CGSize(width: 200, height: 200))
let outImageFill = scaleAndCropImage(img, toSize: CGSize(width: 200, height: 200), fitImage: false)
@erica
Copy link
Author

erica commented May 31, 2016

@PaulTaykalo

In my real world code, I use code that passes a context. You can always get context from a valid drawing session and UIKit supports a context stack, so you can push the context, perform drawing, and then pull an image to return and pop the context.

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