Skip to content

Instantly share code, notes, and snippets.

@licvido
Forked from HamptonMakes/RBResizer.swift
Last active September 18, 2023 11:36
Show Gist options
  • Save licvido/55d12a8eb76a8103c753 to your computer and use it in GitHub Desktop.
Save licvido/55d12a8eb76a8103c753 to your computer and use it in GitHub Desktop.
SWIFT: Crop image to square (& resize)
//
// RBResizer.swift
// Locker
//
// Created by Hampton Catlin on 6/20/14.
// Copyright (c) 2014 rarebit. All rights reserved.
//
import UIKit
func RBSquareImageTo(image: UIImage, size: CGSize) -> UIImage {
return RBResizeImage(RBSquareImage(image), targetSize: size)
}
func RBSquareImage(image: UIImage) -> UIImage {
var originalWidth = image.size.width
var originalHeight = image.size.height
var x: CGFloat = 0.0
var y: CGFloat = 0.0
var edge: CGFloat = 0.0
if (originalWidth > originalHeight) {
// landscape
edge = originalHeight
x = (originalWidth - edge) / 2.0
y = 0.0
} else if (originalHeight > originalWidth) {
// portrait
edge = originalWidth
x = 0.0
y = (originalHeight - originalWidth) / 2.0
} else {
// square
edge = originalWidth
}
var cropSquare = CGRectMake(x, y, edge, edge)
var imageRef = CGImageCreateWithImageInRect(image.CGImage, cropSquare);
return UIImage(CGImage: imageRef, scale: UIScreen.mainScreen().scale, orientation: image.imageOrientation)!
}
func RBResizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
let size = image.size
let widthRatio = targetSize.width / image.size.width
let heightRatio = targetSize.height / image.size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio)
} else {
newSize = CGSizeMake(size.width * widthRatio, size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRectMake(0, 0, newSize.width, newSize.height)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
@jeffreybergier
Copy link

jeffreybergier commented Jan 10, 2018

Hi Hampton,

I was really struggling with this problem and your GIST helped a lot. Thanks! I changed some syntax things to make it work with Swift 4 and the UIGraphicsImageRenderer API. Thanks again for posting this!

extension UIImage {
    
    func resize(toTargetSize targetSize: CGSize) -> UIImage {
        // inspired by Hamptin Catlin
        // https://gist.github.com/licvido/55d12a8eb76a8103c753

        let newScale = self.scale // change this if you want the output image to have a different scale
        let originalSize = self.size

        let widthRatio = targetSize.width / originalSize.width
        let heightRatio = targetSize.height / originalSize.height

        // Figure out what our orientation is, and use that to form the rectangle
        let newSize: CGSize
        if widthRatio > heightRatio {
            newSize = CGSize(width: floor(originalSize.width * heightRatio), height: floor(originalSize.height * heightRatio))
        } else {
            newSize = CGSize(width: floor(originalSize.width * widthRatio), height: floor(originalSize.height * widthRatio))
        }

        // This is the rect that we've calculated out and this is what is actually used below
        let rect = CGRect(origin: .zero, size: newSize)

        // Actually do the resizing to the rect using the ImageContext stuff
        let format = UIGraphicsImageRendererFormat()
        format.scale = newScale
        format.opaque = true
        let newImage = UIGraphicsImageRenderer(bounds: rect, format: format).image() { _ in
            self.draw(in: rect)
        }

        return newImage
    }
}

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