Last active
January 9, 2024 03:13
-
-
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.
This file contains 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
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