Estoy creando una aplicación para iOS usando Swift y Parse.com
Estoy tratando de permitir que el usuario seleccione una imagen de un selector de imágenes y luego cambie el tamaño de la imagen seleccionada a 200x200 píxeles antes de cargarla en mi backend.
Parse.com tiene un tutorial para una aplicación de copia de Instagram llamada "AnyPic" que proporciona este código para cambiar el tamaño de las imágenes, pero está en Objective-C ...
// Resize the image to be square (what is shown in the preview)
UIImage *resizedImage = [anImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
bounds:CGSizeMake(560.0f, 560.0f)
interpolationQuality:kCGInterpolationHigh];
// Create a thumbnail and add a corner radius for use in table views
UIImage *thumbnailImage = [anImage thumbnailImage:86.0f
transparentBorder:0.0f
cornerRadius:10.0f
interpolationQuality:kCGInterpolationDefault];
¿Cómo crearía una versión de 200x200px de la imagen seleccionada (para luego cargarla) en Swift?
Y, ¿qué está haciendo la función thumbnailImage?
UIGraphicsBeginImageContextWithOptions
último parámetro sea,0.0
ya que será la escala del dispositivo.Para Swift 4.0 y iOS 10
extension UIImage { func resizeImage(_ dimension: CGFloat, opaque: Bool, contentMode: UIViewContentMode = .scaleAspectFit) -> UIImage { var width: CGFloat var height: CGFloat var newImage: UIImage let size = self.size let aspectRatio = size.width/size.height switch contentMode { case .scaleAspectFit: if aspectRatio > 1 { // Landscape image width = dimension height = dimension / aspectRatio } else { // Portrait image height = dimension width = dimension * aspectRatio } default: fatalError("UIIMage.resizeToFit(): FATAL: Unimplemented ContentMode") } if #available(iOS 10.0, *) { let renderFormat = UIGraphicsImageRendererFormat.default() renderFormat.opaque = opaque let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: renderFormat) newImage = renderer.image { (context) in self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) } } else { UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), opaque, 0) self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) newImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() } return newImage } }
fuente
myImage.resizeImage(...)
.Dado que la respuesta de @KiritModi es de 2015, esta es la versión de Swift 3.0:
func resizeImage(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 = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }
fuente
Para Swift 4, simplemente haría una extensión en UIImage con referencia a uno mismo.
import UIKit extension UIImage { func resizeImage(targetSize: CGSize) -> UIImage { let size = self.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height let newSize = widthRatio > heightRatio ? CGSize(width: size.width * heightRatio, height: size.height * heightRatio) : CGSize(width: size.width * widthRatio, height: size.height * widthRatio) let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }
fuente
Detalles
Enlaces
Solución
import UIKit import CoreGraphics import Accelerate extension UIImage { public enum ResizeFramework { case uikit, coreImage, coreGraphics, imageIO, accelerate } /// Resize image with ScaleAspectFit mode and given size. /// /// - Parameter dimension: width or length of the image output. /// - Parameter resizeFramework: Technique for image resizing: UIKit / CoreImage / CoreGraphics / ImageIO / Accelerate. /// - Returns: Resized image. func resizeWithScaleAspectFitMode(to dimension: CGFloat, resizeFramework: ResizeFramework = .coreGraphics) -> UIImage? { if max(size.width, size.height) <= dimension { return self } var newSize: CGSize! let aspectRatio = size.width/size.height if aspectRatio > 1 { // Landscape image newSize = CGSize(width: dimension, height: dimension / aspectRatio) } else { // Portrait image newSize = CGSize(width: dimension * aspectRatio, height: dimension) } return resize(to: newSize, with: resizeFramework) } /// Resize image from given size. /// /// - Parameter newSize: Size of the image output. /// - Parameter resizeFramework: Technique for image resizing: UIKit / CoreImage / CoreGraphics / ImageIO / Accelerate. /// - Returns: Resized image. public func resize(to newSize: CGSize, with resizeFramework: ResizeFramework = .coreGraphics) -> UIImage? { switch resizeFramework { case .uikit: return resizeWithUIKit(to: newSize) case .coreGraphics: return resizeWithCoreGraphics(to: newSize) case .coreImage: return resizeWithCoreImage(to: newSize) case .imageIO: return resizeWithImageIO(to: newSize) case .accelerate: return resizeWithAccelerate(to: newSize) } } // MARK: - UIKit /// Resize image from given size. /// /// - Parameter newSize: Size of the image output. /// - Returns: Resized image. private func resizeWithUIKit(to newSize: CGSize) -> UIImage? { UIGraphicsBeginImageContextWithOptions(newSize, true, 1.0) self.draw(in: CGRect(origin: .zero, size: newSize)) defer { UIGraphicsEndImageContext() } return UIGraphicsGetImageFromCurrentImageContext() } // MARK: - CoreImage /// Resize CI image from given size. /// /// - Parameter newSize: Size of the image output. /// - Returns: Resized image. // https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html private func resizeWithCoreImage(to newSize: CGSize) -> UIImage? { guard let cgImage = cgImage, let filter = CIFilter(name: "CILanczosScaleTransform") else { return nil } let ciImage = CIImage(cgImage: cgImage) let scale = (Double)(newSize.width) / (Double)(ciImage.extent.size.width) filter.setValue(ciImage, forKey: kCIInputImageKey) filter.setValue(NSNumber(value:scale), forKey: kCIInputScaleKey) filter.setValue(1.0, forKey: kCIInputAspectRatioKey) guard let outputImage = filter.value(forKey: kCIOutputImageKey) as? CIImage else { return nil } let context = CIContext(options: [.useSoftwareRenderer: false]) guard let resultCGImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil } return UIImage(cgImage: resultCGImage) } // MARK: - CoreGraphics /// Resize image from given size. /// /// - Parameter newSize: Size of the image output. /// - Returns: Resized image. private func resizeWithCoreGraphics(to newSize: CGSize) -> UIImage? { guard let cgImage = cgImage, let colorSpace = cgImage.colorSpace else { return nil } let width = Int(newSize.width) let height = Int(newSize.height) let bitsPerComponent = cgImage.bitsPerComponent let bytesPerRow = cgImage.bytesPerRow let bitmapInfo = cgImage.bitmapInfo guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else { return nil } context.interpolationQuality = .high let rect = CGRect(origin: CGPoint.zero, size: newSize) context.draw(cgImage, in: rect) return context.makeImage().flatMap { UIImage(cgImage: $0) } } // MARK: - ImageIO /// Resize image from given size. /// /// - Parameter newSize: Size of the image output. /// - Returns: Resized image. private func resizeWithImageIO(to newSize: CGSize) -> UIImage? { var resultImage = self guard let data = jpegData(compressionQuality: 1.0) else { return resultImage } let imageCFData = NSData(data: data) as CFData let options = [ kCGImageSourceCreateThumbnailWithTransform: true, kCGImageSourceCreateThumbnailFromImageAlways: true, kCGImageSourceThumbnailMaxPixelSize: max(newSize.width, newSize.height) ] as CFDictionary guard let source = CGImageSourceCreateWithData(imageCFData, nil), let imageReference = CGImageSourceCreateThumbnailAtIndex(source, 0, options) else { return resultImage } resultImage = UIImage(cgImage: imageReference) return resultImage } // MARK: - Accelerate /// Resize image from given size. /// /// - Parameter newSize: Size of the image output. /// - Returns: Resized image. private func resizeWithAccelerate(to newSize: CGSize) -> UIImage? { var resultImage = self guard let cgImage = cgImage, let colorSpace = cgImage.colorSpace else { return nil } // create a source buffer var format = vImage_CGImageFormat(bitsPerComponent: numericCast(cgImage.bitsPerComponent), bitsPerPixel: numericCast(cgImage.bitsPerPixel), colorSpace: Unmanaged.passUnretained(colorSpace), bitmapInfo: cgImage.bitmapInfo, version: 0, decode: nil, renderingIntent: .absoluteColorimetric) var sourceBuffer = vImage_Buffer() defer { sourceBuffer.data.deallocate() } var error = vImageBuffer_InitWithCGImage(&sourceBuffer, &format, nil, cgImage, numericCast(kvImageNoFlags)) guard error == kvImageNoError else { return resultImage } // create a destination buffer let destWidth = Int(newSize.width) let destHeight = Int(newSize.height) let bytesPerPixel = cgImage.bitsPerPixel let destBytesPerRow = destWidth * bytesPerPixel let destData = UnsafeMutablePointer<UInt8>.allocate(capacity: destHeight * destBytesPerRow) defer { destData.deallocate() } var destBuffer = vImage_Buffer(data: destData, height: vImagePixelCount(destHeight), width: vImagePixelCount(destWidth), rowBytes: destBytesPerRow) // scale the image error = vImageScale_ARGB8888(&sourceBuffer, &destBuffer, nil, numericCast(kvImageHighQualityResampling)) guard error == kvImageNoError else { return resultImage } // create a CGImage from vImage_Buffer let destCGImage = vImageCreateCGImageFromBuffer(&destBuffer, &format, nil, nil, numericCast(kvImageNoFlags), &error)?.takeRetainedValue() guard error == kvImageNoError else { return resultImage } // create a UIImage if let scaledImage = destCGImage.flatMap({ UIImage(cgImage: $0) }) { resultImage = scaledImage } return resultImage } }
Uso
import UIKit // https://stackoverflow.com/a/55765409/4488252 extension UIImage { func getFileSizeInfo(allowedUnits: ByteCountFormatter.Units = .useMB, countStyle: ByteCountFormatter.CountStyle = .memory, compressionQuality: CGFloat = 1.0) -> String? { // https://developer.apple.com/documentation/foundation/bytecountformatter let formatter = ByteCountFormatter() formatter.allowedUnits = allowedUnits formatter.countStyle = countStyle return getSizeInfo(formatter: formatter, compressionQuality: compressionQuality) } func getSizeInfo(formatter: ByteCountFormatter, compressionQuality: CGFloat = 1.0) -> String? { guard let imageData = jpegData(compressionQuality: compressionQuality) else { return nil } return formatter.string(fromByteCount: Int64(imageData.count)) } }
private func test() { guard let img = UIImage(named: "img") else { return } printInfo(of: img, title: "original image |") let dimension: CGFloat = 2000 var framework: UIImage.ResizeFramework = .accelerate var startTime = Date() if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) { printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime) } framework = .coreGraphics startTime = Date() if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) { printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime) } framework = .coreImage startTime = Date() if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) { printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime) } framework = .imageIO startTime = Date() if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) { printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime) } framework = .uikit startTime = Date() if let img = img.resizeWithScaleAspectFitMode(to: dimension, resizeFramework: framework) { printInfo(of: img, title: "resized image |", with: framework, startedTime: startTime) } } private func printInfo(of image: UIImage, title: String, with resizeFramework: UIImage.ResizeFramework? = nil, startedTime: Date? = nil) { var description = "\(title) \(image.size)" if let startedTime = startedTime { description += ", execution time: \(Date().timeIntervalSince(startedTime))" } if let fileSize = image.getFileSizeInfo(compressionQuality: 0.9) { description += ", size: \(fileSize)" } if let resizeFramework = resizeFramework { description += ", framework: \(resizeFramework)" } print(description) }
Salida
original image | (5790.0, 8687.0), size: 17.1 MB resized image | (1333.0, 2000.0), execution time: 0.8192930221557617, size: 1.1 MB, framework: accelerate resized image | (1333.0, 2000.0), execution time: 0.44696998596191406, size: 1 MB, framework: coreGraphics resized image | (1334.0, 2000.0), execution time: 54.172922015190125, size: 1.1 MB, framework: coreImage resized image | (1333.0, 2000.0), execution time: 1.8765920400619507, size: 1.1 MB, framework: imageIO resized image | (1334.0, 2000.0), execution time: 0.4638739824295044, size: 1 MB, framework: uikit
fuente
También es posible utilizar AlamofireImage ( https://github.com/Alamofire/AlamofireImage )
let size = CGSize(width: 30.0, height: 30.0) let aspectScaledToFitImage = image.af_imageAspectScaled(toFit: size)
La función en la publicación anterior me dio un resultado borroso.
fuente
Versión Swift 3 y estilo de extensión
Esta respuesta proviene de @Kirit Modi.
extension UIImage { func resizeImage(targetSize: CGSize) -> UIImage { let size = self.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height // Figure out what our orientation is, and use that to form the rectangle var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }
fuente
Para Swift 5.0 y iOS 12
extension UIImage { func imageResized(to size: CGSize) -> UIImage { return UIGraphicsImageRenderer(size: size).image { _ in draw(in: CGRect(origin: .zero, size: size)) } } }
utilizar:
let image = #imageLiteral(resourceName: "ic_search") cell!.search.image = image.imageResized(to: cell!.search.frame.size)
fuente
Swift 4, versión de extensión, SIN LÍNEA BLANCA EN LOS BORDES.
Nadie parece mencionar que si
image.draw()
se llama con valores no enteros, la imagen resultante podría mostrar un artefacto de línea blanca en el borde derecho o inferior.extension UIImage { func scaled(with scale: CGFloat) -> UIImage? { // size has to be integer, otherwise it could get white lines let size = CGSize(width: floor(self.size.width * scale), height: floor(self.size.height * scale)) UIGraphicsBeginImageContext(size) draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image }
fuente
Versión Swift 4
extension UIImage { func resizeImage(_ newSize: CGSize) -> UIImage? { func isSameSize(_ newSize: CGSize) -> Bool { return size == newSize } func scaleImage(_ newSize: CGSize) -> UIImage? { func getScaledRect(_ newSize: CGSize) -> CGRect { let ratio = max(newSize.width / size.width, newSize.height / size.height) let width = size.width * ratio let height = size.height * ratio return CGRect(x: 0, y: 0, width: width, height: height) } func _scaleImage(_ scaledRect: CGRect) -> UIImage? { UIGraphicsBeginImageContextWithOptions(scaledRect.size, false, 0.0); draw(in: scaledRect) let image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage() UIGraphicsEndImageContext() return image } return _scaleImage(getScaledRect(newSize)) } return isSameSize(newSize) ? self : scaleImage(newSize)! } }
fuente
Swift 4.2 versión de @KiritModi respuesta
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let size = image.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! }
fuente
llamada del método resizeimage
let image1 = resizeimage(image: myimage.image!, withSize: CGSize(width:200, height: 200))
método para cambiar el tamaño de la imagen
func resizeimage(image:UIImage,withSize:CGSize) -> UIImage { var actualHeight:CGFloat = image.size.height var actualWidth:CGFloat = image.size.width let maxHeight:CGFloat = withSize.height let maxWidth:CGFloat = withSize.width var imgRatio:CGFloat = actualWidth/actualHeight let maxRatio:CGFloat = maxWidth/maxHeight let compressionQuality = 0.5 if (actualHeight>maxHeight||actualWidth>maxWidth) { if (imgRatio<maxRatio){ //adjust width according to maxHeight imgRatio = maxHeight/actualHeight actualWidth = imgRatio * actualWidth actualHeight = maxHeight }else if(imgRatio>maxRatio){ // adjust height according to maxWidth imgRatio = maxWidth/actualWidth actualHeight = imgRatio * actualHeight actualWidth = maxWidth }else{ actualHeight = maxHeight actualWidth = maxWidth } } let rec:CGRect = CGRect(x:0.0,y:0.0,width:actualWidth,height:actualHeight) UIGraphicsBeginImageContext(rec.size) image.draw(in: rec) let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()! let imageData = UIImageJPEGRepresentation(image, CGFloat(compressionQuality)) UIGraphicsEndImageContext() let resizedimage = UIImage(data: imageData!) return resizedimage! }
fuente
Solución Swift 4
Usa esta función
func image(with image: UIImage, scaledTo newSize: CGSize) -> UIImage { UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() drawingImageView.image = newImage return newImage ?? UIImage() }
Llamar a una función: -
image(with: predictionImage, scaledTo: CGSize(width: 28.0, height: 28.0)
aquí 28.0 es el tamaño de píxel que desea configurar
fuente
Aquí hay un método general (en Swift 5) para reducir la escala de una imagen para que se ajuste a un tamaño. La imagen resultante puede tener la misma relación de aspecto que la original, o puede tener el tamaño de destino con la imagen original centrada en ella. Si la imagen es más pequeña que el tamaño de destino, no se cambia de tamaño.
extension UIImage { func scaledDown(into size:CGSize, centered:Bool = false) -> UIImage { var (targetWidth, targetHeight) = (self.size.width, self.size.height) var (scaleW, scaleH) = (1 as CGFloat, 1 as CGFloat) if targetWidth > size.width { scaleW = size.width/targetWidth } if targetHeight > size.height { scaleH = size.height/targetHeight } let scale = min(scaleW,scaleH) targetWidth *= scale; targetHeight *= scale let sz = CGSize(width:targetWidth, height:targetHeight) if !centered { return UIGraphicsImageRenderer(size:sz).image { _ in self.draw(in:CGRect(origin:.zero, size:sz)) } } let x = (size.width - targetWidth)/2 let y = (size.height - targetHeight)/2 let origin = CGPoint(x:x,y:y) return UIGraphicsImageRenderer(size:size).image { _ in self.draw(in:CGRect(origin:origin, size:sz)) } } }
fuente
Todas las respuestas enumeradas hasta ahora parecen dar como resultado una imagen de tamaño reducido, sin embargo, el tamaño no se mide en píxeles. Aquí hay un cambio de tamaño basado en píxeles de Swift 5 .
extension UIImage { func resize(_ max_size: CGFloat) -> UIImage { // adjust for device pixel density let max_size_pixels = max_size / UIScreen.main.scale // work out aspect ratio let aspectRatio = size.width/size.height // variables for storing calculated data var width: CGFloat var height: CGFloat var newImage: UIImage if aspectRatio > 1 { // landscape width = max_size_pixels height = max_size_pixels / aspectRatio } else { // portrait height = max_size_pixels width = max_size_pixels * aspectRatio } // create an image renderer of the correct size let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: UIGraphicsImageRendererFormat.default()) // render the image newImage = renderer.image { (context) in self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) } // return the image return newImage } }
Uso:
image.resize(500)
fuente
El ejemplo es para minimizar la imagen a 1024 y menos
func resizeImage (imagen: UIImage) -> UIImage {
if image.size.height >= 1024 && image.size.width >= 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:1024)) image.draw(in: CGRect(x:0, y:0, width:1024, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.height >= 1024 && image.size.width < 1024 { UIGraphicsBeginImageContext(CGSize(width:image.size.width, height:1024)) image.draw(in: CGRect(x:0, y:0, width:image.size.width, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.width >= 1024 && image.size.height < 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:image.size.height)) image.draw(in: CGRect(x:0, y:0, width:1024, height:image.size.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else { return image } }
fuente
Puede usar esto para ajustar la imagen en Swift 3 ;
extension UIImage { func resizedImage(newSize: CGSize) -> UIImage { // Guard newSize is different guard self.size != newSize else { return self } UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0); self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 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 = CGSize(width: size.width/resizeFactor, height: size.height/resizeFactor) let resized = resizedImage(newSize: newSize) return resized } }
Uso;
let resizedImage = image.resizedImageWithinRect(rectSize: CGSize(width: 1900, height: 1900))
fuente
Aquí tienes dos funciones simples de
UIImage
extensión:func scaledWithMaxWidthOrHeightValue(value: CGFloat) -> UIImage? { let width = self.size.width let height = self.size.height let ratio = width/height var newWidth = value var newHeight = value if ratio > 1 { newWidth = width * (newHeight/height) } else { newHeight = height * (newWidth/width) } UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0) draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } func scaled(withScale scale: CGFloat) -> UIImage? { let size = CGSize(width: self.size.width * scale, height: self.size.height * scale) UIGraphicsBeginImageContextWithOptions(size, false, 0) draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image }
fuente
UIimage
.Incluyendo aquí mi versión de la respuesta aceptada para que funcione bien con Swift 5. Esta solución no obliga a desenvolver la imagen resultante, lo que la hace una solución un poco más segura y más limpia en general.
extension UIImage { public func resized(to target: CGSize) -> UIImage? { let ratio = min( target.height / size.height, target.width / size.width ) let new = CGSize( width: size.width * ratio, height: size.height * ratio ) UIGraphicsBeginImageContextWithOptions(new, false, 1.0) draw(in: CGRect(origin: .zero, size: new)) defer { UIGraphicsEndImageContext() } return UIGraphicsGetImageFromCurrentImageContext() } }
fuente
Extensión de UIImage Swift 5
extension UIImage { func resize(_ width: CGFloat, _ height:CGFloat) -> UIImage? { let widthRatio = width / size.width let heightRatio = height / size.height let ratio = widthRatio > heightRatio ? heightRatio : widthRatio let newSize = CGSize(width: size.width * ratio, height: size.height * ratio) let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } }
Uso: UIImage (). Resize (200, 300)
fuente
SWIFT 5 con
newImage = UIImage(cgImage: cgImage)
func scaleImage(toSize newSize: CGSize) -> UIImage? { var newImage: UIImage? let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral UIGraphicsBeginImageContextWithOptions(newSize, false, 0) if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage { context.interpolationQuality = .high let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height) context.concatenate(flipVertical) context.draw(cgImage, in: newRect) newImage = UIImage(cgImage: cgImage) UIGraphicsEndImageContext() } return newImage }
fuente