create ios swift uiimage

ios - create uiimageview programmatically swift 4



¿Cómo cambio el tamaño del UIImage para reducir el tamaño de carga de la imagen? (15)

He estado buscando en Google y solo he encontrado bibliotecas que reducen el alto / ancho o de alguna manera editan la apariencia UIImage a través de CoreImage. Pero no he visto ni encontrado una biblioteca, publicación que explica cómo reducir el tamaño de la imagen, por lo que cuando se carga, no es el tamaño completo de la imagen.

hasta ahora tengo esto:

if image != nil { //let data = NSData(data: UIImagePNGRepresentation(image)) let data = UIImagePNGRepresentation(image) body.appendString("--/(boundary)/r/n") body.appendString("Content-Disposition: form-data; name=/"image/"; filename=/"randomName/"/r/n") body.appendString("Content-Type: image/png/r/n/r/n") body.appendData(data) body.appendString("/r/n") }

y está enviando fotos de 12MB. ¿Cómo puedo reducir esto a 1mb? ¡Gracias!


Aquí está la respuesta del usuario4261201, pero de manera rápida, que estoy usando actualmente:

func compressImage (_ image: UIImage) -> UIImage { let actualHeight:CGFloat = image.size.height let actualWidth:CGFloat = image.size.width let imgRatio:CGFloat = actualWidth/actualHeight let maxWidth:CGFloat = 1024.0 let resizedHeight:CGFloat = maxWidth/imgRatio let compressionQuality:CGFloat = 0.5 let rect:CGRect = CGRect(x: 0, y: 0, width: maxWidth, height: resizedHeight) UIGraphicsBeginImageContext(rect.size) image.draw(in: rect) let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()! let imageData:Data = UIImageJPEGRepresentation(img, compressionQuality)! UIGraphicsEndImageContext() return UIImage(data: imageData)! }


Basado en la respuesta de Tung Fam. Para cambiar el tamaño a un tamaño de archivo específico. Como 0,7 MB, puede usar este código.

extension UIImage { func resize(withPercentage percentage: CGFloat) -> UIImage? { var newRect = CGRect(origin: .zero, size: CGSize(width: size.width*percentage, height: size.height*percentage)) UIGraphicsBeginImageContextWithOptions(newRect.size, true, 1) self.draw(in: newRect) defer {UIGraphicsEndImageContext()} return UIGraphicsGetImageFromCurrentImageContext() } func resizeTo(MB: Double) -> UIImage? { guard let fileSize = self.pngData()?.count else {return nil} let fileSizeInMB = CGFloat(fileSize)/(1024.0*1024.0)//form bytes to MB let percentage = 1/fileSizeInMB return resize(withPercentage: percentage) } }


Cambiar el tamaño del UIImage usando .resizeToMaximumBytes


Con esto, puede controlar el tamaño que desee:

func jpegImage(image: UIImage, maxSize: Int, minSize: Int, times: Int) -> Data? { var maxQuality: CGFloat = 1.0 var minQuality: CGFloat = 0.0 var bestData: Data? for _ in 1...times { let thisQuality = (maxQuality + minQuality) / 2 guard let data = image.jpegData(compressionQuality: thisQuality) else { return nil } let thisSize = data.count if thisSize > maxSize { maxQuality = thisQuality } else { minQuality = thisQuality bestData = data if thisSize > minSize { return bestData } } } return bestData }

Ejemplo de llamada de método:

jpegImage(image: image, maxSize: 500000, minSize: 400000, times: 10)

Intentará obtener un archivo entre un tamaño máximo y mínimo de maxSize y minSize, pero solo lo intentará veces. Si falla dentro de ese tiempo, regresará nulo.


Creo que la forma más fácil es proporcionar swift para comprimir la imagen en los datos comprimidos a continuación es el código en swift 4.2

let imageData = yourImageTobeCompressed.jpegData(compressionQuality: 0.5)

y puedes enviar este imageData para subirlo al servidor.


Cuando trato de usar la respuesta aceptada para cambiar el tamaño de una imagen para usar en mi proyecto, sale muy pixelada y borrosa. Terminé con este fragmento de código para cambiar el tamaño de las imágenes sin agregar pixelación o desenfoque:

func scale(withPercentage percentage: CGFloat)-> UIImage? { let cgSize = CGSize(width: size.width * percentage, height: size.height * percentage) let hasAlpha = true let scale: CGFloat = 0.0 // Use scale factor of main screen UIGraphicsBeginImageContextWithOptions(cgSize, !hasAlpha, scale) self.draw(in: CGRect(origin: CGPoint.zero, size: cgSize)) let scaledImage = UIGraphicsGetImageFromCurrentImageContext() return scaledImage }


En caso de que alguien esté buscando cambiar el tamaño de la imagen a menos de 1 MB con Swift 3 y 4 .

Simplemente copie y pegue esta extensión:

extension UIImage { func resized(withPercentage percentage: CGFloat) -> UIImage? { let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage) UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale) defer { UIGraphicsEndImageContext() } draw(in: CGRect(origin: .zero, size: canvasSize)) return UIGraphicsGetImageFromCurrentImageContext() } func resizedTo1MB() -> UIImage? { guard let imageData = UIImagePNGRepresentation(self) else { return nil } var resizingImage = self var imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB while imageSizeKB > 1000 { // ! Or use 1024 if you need KB but not kB guard let resizedImage = resizingImage.resized(withPercentage: 0.9), let imageData = UIImagePNGRepresentation(resizedImage) else { return nil } resizingImage = resizedImage imageSizeKB = Double(imageData.count) / 1000.0 // ! Or devide for 1024 if you need KB but not kB } return resizingImage } }

Y uso:

let resizedImage = originalImage.resizedTo1MB()

Editar: tenga en cuenta que está bloqueando la interfaz de usuario , así que pase al hilo de fondo si cree que es la forma correcta para su caso.


Este es el camino que seguí para cambiar el tamaño de la imagen.

-(UIImage *)resizeImage:(UIImage *)image { float actualHeight = image.size.height; float actualWidth = image.size.width; float maxHeight = 300.0; float maxWidth = 400.0; float imgRatio = actualWidth/actualHeight; float maxRatio = maxWidth/maxHeight; float compressionQuality = 0.5;//50 percent compression 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; } } CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight); UIGraphicsBeginImageContext(rect.size); [image drawInRect:rect]; UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality); UIGraphicsEndImageContext(); return [UIImage imageWithData:imageData]; }

Usando este método, mi imagen con 6.5 MB se redujo a 104 KB.

Código Swift 4:

func resize(_ image: UIImage) -> UIImage { var actualHeight = Float(image.size.height) var actualWidth = Float(image.size.width) let maxHeight: Float = 300.0 let maxWidth: Float = 400.0 var imgRatio: Float = actualWidth / actualHeight let maxRatio: Float = maxWidth / maxHeight let compressionQuality: Float = 0.5 //50 percent compression 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 rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight)) UIGraphicsBeginImageContext(rect.size) image.draw(in: rect) let img = UIGraphicsGetImageFromCurrentImageContext() let imageData = img?.jpegData(compressionQuality: CGFloat(compressionQuality)) UIGraphicsEndImageContext() return UIImage(data: imageData!) ?? UIImage() }


Esto es lo que hice en Swift 3 para cambiar el tamaño de un UIImage. Reduce el tamaño de la imagen a menos de 100 kb. ¡Funciona proporcionalmente!

extension UIImage { class func scaleImageWithDivisor(img: UIImage, divisor: CGFloat) -> UIImage { let size = CGSize(width: img.size.width/divisor, height: img.size.height/divisor) UIGraphicsBeginImageContext(size) img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let scaledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return scaledImage! } }

Uso:

let scaledImage = UIImage.scaleImageWithDivisor(img: capturedImage!, divisor: 3)


Lo mismo en Objective-C:

interfaz :

@interface UIImage (Resize) - (UIImage *)resizedWithPercentage:(CGFloat)percentage; - (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality; @end

implementación:

#import "UIImage+Resize.h" @implementation UIImage (Resize) - (UIImage *)resizedWithPercentage:(CGFloat)percentage { CGSize canvasSize = CGSizeMake(self.size.width * percentage, self.size.height * percentage); UIGraphicsBeginImageContextWithOptions(canvasSize, false, self.scale); [self drawInRect:CGRectMake(0, 0, canvasSize.width, canvasSize.height)]; UIImage *sizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return sizedImage; } - (UIImage *)resizeTo:(CGFloat)weight isPng:(BOOL)isPng jpegCompressionQuality:(CGFloat)compressionQuality { NSData *imageData = isPng ? UIImagePNGRepresentation(self) : UIImageJPEGRepresentation(self, compressionQuality); if (imageData && [imageData length] > 0) { UIImage *resizingImage = self; double imageSizeKB = [imageData length] / weight; while (imageSizeKB > weight) { UIImage *resizedImage = [resizingImage resizedWithPercentage:0.9]; imageData = isPng ? UIImagePNGRepresentation(resizedImage) : UIImageJPEGRepresentation(resizedImage, compressionQuality); resizingImage = resizedImage; imageSizeKB = (double)(imageData.length / weight); } return resizingImage; } return nil; }

Uso:

#import "UIImage+Resize.h" UIImage *resizedImage = [self.picture resizeTo:2048 isPng:NO jpegCompressionQuality:1.0];


Si está cargando una imagen en formato NSData , use esto:

let imagedata = yourImage.jpegData(compressionQuality: 0.1)!

yourImage es tu UIImage . floatvalue es el valor de compresión (0.0 a 1.0)

Lo anterior es para convertir la imagen a JPEG .

Para uso en PNG : UIImagePNGRepresentation

Nota: El código anterior está en Objective-C. Verifique cómo definir NSData en Swift.


Swift4.2

NSData *imageData = UIImageJPEGRepresentation(yourImage, floatValue);


Xcode 9 • Swift 4 o posterior

editar / actualizar: Para iOS10 + podemos usar UIGraphicsImageRenderer . Para ver la sintaxis Swift anterior, verifique el historial de edición

extension UIImage { func resized(withPercentage percentage: CGFloat) -> UIImage? { let canvas = CGSize(width: size.width * percentage, height: size.height * percentage) return UIGraphicsImageRenderer(size: canvas, format: imageRendererFormat).image { _ in draw(in: CGRect(origin: .zero, size: canvas)) } } func resized(toWidth width: CGFloat) -> UIImage? { let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height))) return UIGraphicsImageRenderer(size: canvas, format: imageRendererFormat).image { _ in draw(in: CGRect(origin: .zero, size: canvas)) } } }

Uso:

let image = UIImage(data: try! Data(contentsOf: URL(string:"http://i.stack.imgur.com/Xs4RX.jpg")!))! let thumb1 = image.resized(withPercentage: 0.1) let thumb2 = image.resized(toWidth: 72.0)


igual que Leo Answer pero pequeñas ediciones para SWIFT 2.0

extension UIImage { func resizeWithPercentage(percentage: CGFloat) -> UIImage? { let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: size.width * percentage, height: size.height * percentage))) imageView.contentMode = .ScaleAspectFit imageView.image = self UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale) guard let context = UIGraphicsGetCurrentContext() else { return nil } imageView.layer.renderInContext(context) guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil } UIGraphicsEndImageContext() return result } func resizeWithWidth(width: CGFloat) -> UIImage? { let imageView = UIImageView(frame: CGRect(origin: .zero, size: CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height))))) imageView.contentMode = .ScaleAspectFit imageView.image = self UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale) guard let context = UIGraphicsGetCurrentContext() else { return nil } imageView.layer.renderInContext(context) guard let result = UIGraphicsGetImageFromCurrentImageContext() else { return nil } UIGraphicsEndImageContext() return result } }


extension UIImage { func resized(toValue value: CGFloat) -> UIImage { if size.width > size.height { return self.resize(toWidth: value)! } else { return self.resize(toHeight: value)! } }