Skip to content

Instantly share code, notes, and snippets.

@viccc
Last active January 9, 2024 03:13
Show Gist options
  • Save viccc/aecb97c482ee7f76cca4 to your computer and use it in GitHub Desktop.
Save viccc/aecb97c482ee7f76cca4 to your computer and use it in GitHub Desktop.
Resize+crop image to a smaller size (using scale aspect fill logic), if image is indeed larger than required size. In Swift.
func downscaleImage(image: UIImage, toPixelSize targetSize: CGSize) -> UIImage {
return downscaleImage(image, toSize: targetSize, scale: 1.0)
}
func downscaleImage(image: UIImage, toSize targetSize: CGSize, scale: CGFloat = 0.0) -> UIImage {
let actualScaleFactor = (scale == 0.0) ? UIScreen.mainScreen().scale : scale
let size = image.size
let imageScaleFactor = image.scale
let imagePixelSize = CGSizeMake(size.width * imageScaleFactor, size.height * imageScaleFactor)
let requiredMinPixelSize = CGSizeMake(targetSize.width * actualScaleFactor, targetSize.height * actualScaleFactor)
let canBeDownscaled = (requiredMinPixelSize.width < imagePixelSize.width) && (requiredMinPixelSize.height < imagePixelSize.height)
if !canBeDownscaled {
return image
}
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// This part is based on https://gist.github.com/hcatlin/180e81cd961573e3c54d
// but it fixes the bug with wrong ratio used
let downscaledImageSize: CGSize
if (widthRatio > heightRatio) {
downscaledImageSize = CGSizeMake(size.width * widthRatio, size.height * widthRatio)
} else {
downscaledImageSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio)
}
let imageRect: CGRect
if CGSizeEqualToSize(downscaledImageSize, targetSize) {
imageRect = CGRectMake(0, 0, targetSize.width, targetSize.height)
} else {
let xDiff = (downscaledImageSize.width > targetSize.width) ? 0.5 * (downscaledImageSize.width - targetSize.width) : 0.0
let yDiff = (downscaledImageSize.height > targetSize.height) ? 0.5 * (downscaledImageSize.height - targetSize.height) : 0.0
imageRect = CGRectMake(-xDiff, -yDiff, downscaledImageSize.width, downscaledImageSize.height)
}
UIGraphicsBeginImageContextWithOptions(targetSize, false, scale)
image.drawInRect(imageRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment