La carga de imágenes con la aplicación IOS en el tamaño del file del server es demasiado grande.

Estoy subiendo fotos a un server con una aplicación iOS. Es importante que las fotos se carguen sin pérdida de calidad y se carguen como jpeg. Mi problema actual es que las fotos se carguen sin pérdida de calidad pero tienen un tamaño de file mayor de lo esperado. Por ejemplo: subí un file a través de la aplicación y el tamaño del file fue de 4.7 MB. Cuando envié por correo electrónico la misma foto a mí mismo y seleccioné la opción "Foto real" para el correo electrónico, el tamaño de la foto era solo de 1,7 MB. Una comparación de lado a lado no reveló diferencias en la calidad.

Aquí es cómo subo los files.

ALAssetsLibrary *library = [ALAssetsLibrary new]; [library getImageAtURL:orderImage.imageUrl with completionBlock:^(UIImage *image) NSData *fileData = UIImageJPEGRepresentation(image, 1.0) NSURLRequest *request = [self multipartFormRequestWithMethod:@"POST" path:path parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileData:fileData name:@"uploadedfile" fileName:fileName mimeType:mimeType]; [formData appendPartWithFormData:[extraInfo dataUsingEncoding:NSISOLatin2StringEncoding] name:@"extraInfo"]; }]; 

    El problema es UIImageJPEGRepresentation . No recupera el JPEG original, sino que crea un nuevo JPEG. Y cuando usa una calidad de compressionQuality de 1 (presumiblemente para evitar más pérdida de calidad de image), crea esta nueva representación sin compression (generalmente resulta en un file más grande que el original).

    Le aconsejaría usar getBytes para recuperar el activo original, en lugar de dispararlo a través de un UIImage y get los datos a través de UIImageJPEGRepresentation :

     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:assetsLibraryURL resultBlock:^(ALAsset *asset) { ALAssetRepresentation *representation = [asset defaultRepresentation]; // I generally would write directly to a `NSOutputStream`, but if you want it in a // NSData, it would be something like: NSMutableData *data = [NSMutableData data]; // now loop, reading data into buffer and writing that to our data stream NSError *error; long long bufferOffset = 0ll; NSInteger bufferSize = 10000; long long bytesRemaining = [representation size]; uint8_t buffer[bufferSize]; while (bytesRemaining > 0) { NSUInteger bytesRead = [representation getBytes:buffer fromOffset:bufferOffset length:bufferSize error:&error]; if (bytesRead == 0) { NSLog(@"error reading asset representation: %@", error); return; } bytesRemaining -= bytesRead; bufferOffset += bytesRead; [data appendBytes:buffer length:bytesRead]; } // ok, successfully read original asset; // do whatever you want with it here } failureBlock:^(NSError *error) { NSLog(@"error=%@", error); }]; 

    Si está utilizando el marco de fotos presentado en iOS 8, puede usar PHImageManager para get los datos de image:

     PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[assetsLibraryURL] options:nil]; PHAsset *asset = [result firstObject]; if (asset) { PHImageManager *manager = [PHImageManager defaultManager]; [manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { // use `imageData` here }]; }