ios - pasar - ¿Cómo comprimir/cambiar el tamaño de la imagen en iPhone OS SDK antes de cargarlo en un servidor?
ios 12 iphone 6 (13)
Actualmente estoy cargando una imagen a un servidor usando Imgur en iOS con el siguiente código:
NSData* imageData = UIImagePNGRepresentation(image);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SBTempImage.png"];
[imageData writeToFile:fullPathToFile atomically:NO];
[uploadRequest setFile:fullPathToFile forKey:@"image"];
El código funciona bien cuando se ejecuta en el simulador y carga un archivo de la biblioteca de fotos del simulador porque tengo una conexión rápida de Ethernet. Sin embargo, el mismo código caduca en el iPhone al seleccionar una imagen tomada con el iPhone. Entonces, lo intenté guardando una pequeña imagen de la web e intentando subir eso, lo que funcionó.
Esto me lleva a creer que las grandes imágenes tomadas por el iPhone se están agotando en la lenta red 3G. ¿Hay alguna forma de comprimir / cambiar el tamaño de la imagen desde el iPhone antes de enviarlo?
¡Gracias!
Debería poder hacer una imagen más pequeña haciendo algo como
UIImage *small = [UIImage imageWithCGImage:original.CGImage scale:0.25 orientation:original.imageOrientation];
(para una imagen de un cuarto de tamaño) luego convierta la imagen más pequeña en PNG o en el formato que necesite.
En este código, 0.5 significa 50% ...
UIImage *original = image;
UIImage *compressedImage = UIImageJPEGRepresentation(original, 0.5f);
Este fragmento cambiará el tamaño de la imagen:
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
La variable newSize
es un CGSize
y se puede definir así:
CGSize newSize = CGSizeMake(100.0f, 100.0f);
Implementación rápida de la función de Zorayr (con un poco de cambio para incluir restricciones de altura o ancho por unidades reales, no escala):
class func compressForUpload(original:UIImage, withHeightLimit heightLimit:CGFloat, andWidthLimit widthLimit:CGFloat)->UIImage{
let originalSize = original.size
var newSize = originalSize
if originalSize.width > widthLimit && originalSize.width > originalSize.height {
newSize.width = widthLimit
newSize.height = originalSize.height*(widthLimit/originalSize.width)
}else if originalSize.height > heightLimit && originalSize.height > originalSize.width {
newSize.height = heightLimit
newSize.width = originalSize.width*(heightLimit/originalSize.height)
}
// Scale the original image to match the new size.
UIGraphicsBeginImageContext(newSize)
original.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let compressedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return compressedImage
}
Las MGImageUtilities Matt Gemmell son muy bonitas, MGImageUtilities tamaño de manera eficiente y con algunos métodos para reducir el esfuerzo.
Para complementar a @Tuan Nguyen, esta es quizás la manera más rápida y elegante de hacerlo.
Para vincular a la publicación de John Muchow en iphonedevelopertips.com , agregar una categoría a un UIImage es una forma muy práctica de escalar de una manera muy rápida. Solo llamando
UIImage *_image = [[[UIImage alloc] initWithData:SOME_NSDATA] scaleToSize:CGSizeMake(640.0,480.0)];
le devuelve una imagen de representación de 640x480 de su NSDATA (que podría ser una imagen en línea) sin más líneas de código.
Swift 2.0 versión del método de Jagandeep Singh pero necesita convertir datos a imagen porque NSData? no se convierte UIImage automáticamente.
let orginalImage:UIImage = image
let compressedData = UIImageJPEGRepresentation(orginalImage, 0.5)
let compressedImage = UIImage(data: compressedData!)
Una solución autónoma:
- (UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
{
// Calculate new size given scale factor.
CGSize originalSize = original.size;
CGSize newSize = CGSizeMake(originalSize.width * scale, originalSize.height * scale);
// Scale the original image to match the new size.
UIGraphicsBeginImageContext(newSize);
[original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *compressedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return compressedImage;
}
Gracias a @Tuan Nguyen.
utilice este método simple NSData *data = UIImageJPEGRepresentation(chosenImage, 0.2f);
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
+ (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
NSData *imageData = UIImagePNGRepresentation(image);
CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
(id) kCGImageSourceCreateThumbnailWithTransform : @YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
(id) kCGImageSourceThumbnailMaxPixelSize : @(resolution)
};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
return img;
}
-(UIImage *) resizeImage:(UIImage *)orginalImage resizeSize:(CGSize)size
{
CGFloat actualHeight = orginalImage.size.height;
CGFloat actualWidth = orginalImage.size.width;
// if(actualWidth <= size.width && actualHeight<=size.height)
// {
// return orginalImage;
// }
float oldRatio = actualWidth/actualHeight;
float newRatio = size.width/size.height;
if(oldRatio < newRatio)
{
oldRatio = size.height/actualHeight;
actualWidth = oldRatio * actualWidth;
actualHeight = size.height;
}
else
{
oldRatio = size.width/actualWidth;
actualHeight = oldRatio * actualHeight;
actualWidth = size.width;
}
CGRect rect = CGRectMake(0.0,0.0,actualWidth,actualHeight);
UIGraphicsBeginImageContext(rect.size);
[orginalImage drawInRect:rect];
orginalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return orginalImage;
}
Este es el método de llamar
UIImage *compimage=[appdel resizeImage:imagemain resizeSize:CGSizeMake(40,40)];
devuelve la imagen esta imagen puede mostrar en cualquier lugar ...........
NsData *data=UiImageJPEGRepresentation(Img.image,0.2f);
UIImage *image = [UIImage imageNamed:@"image.png"];
NSData *imgData1 = UIImageJPEGRepresentation(image, 1);
NSLog(@"Original --- Size of Image(bytes):%d",[imgData1 length]);
NSData *imgData2 = UIImageJPEGRepresentation(image, 0.5);
NSLog(@"After --- Size of Image(bytes):%d",[imgData2 length]);
image = [UIImage imageWithData:imgData2];
imgTest.image = image;
intente convertir JPG por factor de escala. Aquí estoy usando 0.5 En mi caso: Original --- Tamaño de la imagen (bytes): 85 KB y después --- Tamaño de la imagen (bytes): 23 KB