Загрузка изображения с помощью приложения IOS на сервер слишком велика

Я загружаю фотографии на сервер с приложением IOS. Важно, чтобы фотографии загружались без потери качества и загружались в формате JPEG. Моя текущая проблема заключается в том, что фотографии загружаются без потери качества, но их размер превышает ожидаемый. Например: я загрузил файл через приложение, и его размер составил 4,7 МБ. Когда я отправил мне ту же фотографию по электронной почте и выбрал опцию "Фактическая фотография" для электронной почты, размер фотографии составил всего 1,7 МБ. Сравнение сторон не выявило различий в качестве.

Вот как я загружаю файлы.

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"];
}];

1 ответ

Решение

Проблема в UIImageJPEGRepresentation, Он не извлекает исходный JPEG, а создает новый JPEG. И когда вы используете compressionQuality из 1 (предположительно, чтобы избежать дальнейшей потери качества изображения), он создает это новое представление без сжатия (обычно в результате получается файл, больший, чем оригинал).

Я бы посоветовал использовать getBytes чтобы получить исходный актив, а не обойти его через UIImage и получение данных через 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);
}];

-

Если вы используете фреймворк Photos, представленный в iOS 8, можете использовать PHImageManager чтобы получить данные изображения:

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
    }];
}
Другие вопросы по тегам