Descubrí que es difícil encontrar una respuesta que pueda usar de forma inmediata en su proyecto Swift 3 . El principal problema de otras respuestas es que no respetan el canal alfa de la imagen. Aquí está la técnica que estoy usando en mis proyectos.
extension UIImage {
func scaledToFit(toSize newSize: CGSize) -> UIImage {
if (size.width < newSize.width && size.height < newSize.height) {
return copy() as! UIImage
}
let widthScale = newSize.width / size.width
let heightScale = newSize.height / size.height
let scaleFactor = widthScale < heightScale ? widthScale : heightScale
let scaledSize = CGSize(width: size.width * scaleFactor, height: size.height * scaleFactor)
return self.scaled(toSize: scaledSize, in: CGRect(x: 0.0, y: 0.0, width: scaledSize.width, height: scaledSize.height))
}
func scaled(toSize newSize: CGSize, in rect: CGRect) -> UIImage {
if UIScreen.main.scale == 2.0 {
UIGraphicsBeginImageContextWithOptions(newSize, !hasAlphaChannel, 2.0)
}
else {
UIGraphicsBeginImageContext(newSize)
}
draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage ?? UIImage()
}
var hasAlphaChannel: Bool {
guard let alpha = cgImage?.alphaInfo else {
return false
}
return alpha == CGImageAlphaInfo.first ||
alpha == CGImageAlphaInfo.last ||
alpha == CGImageAlphaInfo.premultipliedFirst ||
alpha == CGImageAlphaInfo.premultipliedLast
}
}
Ejemplo de uso:
override func viewDidLoad() {
super.viewDidLoad()
let size = CGSize(width: 14.0, height: 14.0)
if let image = UIImage(named: "barbell")?.scaledToFit(toSize: size) {
let imageView = UIImageView(image: image)
imageView.center = CGPoint(x: 100, y: 100)
view.addSubview(imageView)
}
}
Este código es una reescritura de la extensión de Apple con soporte adicional para imágenes con y sin canal alfa.
Como lectura adicional, recomiendo consultar este artículo para conocer diferentes técnicas de cambio de tamaño de imagen. El enfoque actual ofrece un rendimiento decente, opera API de alto nivel y es fácil de entender. Recomiendo mantenerlo a menos que encuentre que el cambio de tamaño de la imagen es un cuello de botella en su rendimiento.