read

Erica Sadun posted a Swift rewrite challenge, and the chosen function is to scale and crop an image.

Resizing a UIImage is a very common task.

I have written it a couple of times, in Objective-C, and recently in Swift.

While I am not partaking in the challenge, it is helpful to look at the different implementations, learn from them, and improve my version.

My Improved Code

import UIKit

extension UIImage {
    
    /// Returns a image that fills in newSize
    func resizedImage(newSize: CGSize) -> UIImage {
        // Guard newSize is different
        guard self.size != newSize else { return self }
        
        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
        self.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    
    /// Returns a resized image that fits in rectSize, keeping it's aspect ratio
    /// Note that the new image size is not rectSize, but within it.
    func resizedImageWithinRect(rectSize: CGSize) -> UIImage {
        let widthFactor = size.width / rectSize.width
        let heightFactor = size.height / rectSize.height
        
        var resizeFactor = widthFactor
        if size.height > size.width {
            resizeFactor = heightFactor
        }
        
        let newSize = CGSizeMake(size.width/resizeFactor, size.height/resizeFactor)
        let resized = resizedImage(newSize)
        return resized
    }
    
}

// Tests
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 = img.resizedImageWithinRect(CGSize(width: 200, height: 200))
let outImageFill = img.resizedImage(CGSize(width: 200, height: 200))

It is my duty to point out the 0.0 passed in UIGraphicsBeginImageContextWithOptions is to make sure the image scale gracefully in retina devices.


Image

@samwize

¯\_(ツ)_/¯

Back to Home