Уменьшите размер UIImage до управляемого размера (уменьшите байты)

Я хочу уменьшить количество байтов изображения, захваченного устройством, так как я считаю, что _imageScaledToSize не уменьшает количество байтов изображения (или уменьшает?) - я хочу сохранить миниатюру изображения в локальном словарь и не может позволить себе помещать в словарь полноразмерные изображения. Есть идеи?


person Mustafa    schedule 28.01.2009    source источник
comment
да. также изменить описание, чтобы сделать его более понятным. Я думаю, что многие люди находят это расплывчатым или неясным.   -  person Mustafa    schedule 29.01.2009


Ответы (5)


Если вы хотите просто сжать свой UIImage, вы можете использовать

NSData *dataForPNGFile = UIImagePNGRepresentation(yourImage);

для создания версии NSData вашего изображения, закодированного как PNG (легко вставленного в NSDictionary или записанного на диск), или вы можете использовать

NSData *dataForPNGFile = UIImageJPEGRepresentation(yourImage, 0.9f);

сделать то же самое, только в формате JPEG. Второй параметр — качество изображения JPEG. Оба они должны создавать изображения, которые меньше по объему памяти, чем ваш UIImage.

Изменение размера UIImage для создания миниатюры меньшего размера (в пикселях) с использованием опубликованных методов немного сложнее. _imageScaledToSize — это частный API, и я настоятельно рекомендую вам не использовать его. Чтобы узнать о способах, которые работают в рамках задокументированных методов, см. эту публикацию.

person Brad Larson    schedule 30.01.2009

Я столкнулся с этой проблемой на днях и провел довольно много исследований. Я нашел отличное решение с кодом здесь:

http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

person radesix    schedule 06.03.2010
comment
Это хорошая реализация, но она плохо обрабатывает некоторые нетипичные форматы изображений. См. stackoverflow.com/a/10491692/1271826 для категории изменения размера UIImage, которая не страдает от этой проблемы. - person Rob; 05.02.2014

Вам нужно нарисовать изображение в графическом контексте меньшего размера. Затем отпустите исходное изображение.

person Community    schedule 28.01.2009
comment
«уменьшить байты» «физический размер, а не размер измерения» Я верю, что он хочет сжать изображение без изменения его размеров. - person Peter Hosey; 29.01.2009
comment
Да, я думаю, ты прав. Я неправильно истолковал это как то, что хочу уменьшить количество пикселей, а не уменьшить общие размеры. - person Mike Abdullah; 29.01.2009

Когда вы говорите «физический размер», вы имеете в виду отпечаток? Потому что вы можете просто изменить размер страницы принтера.

Вы говорите о количестве пикселей, используемых для захвата изображения? Например, если у вас есть массив пикселей 3000x2000, а вам нужен только размер 150x150, вы можете обрезать изображения. Во время захвата, если у вас есть научный тепловизор, вы можете просто установить область, которая будет захвачена. Драйвер камеры будет содержать инструкции для этого. Если вы хотите захватить 3000x2000 в 1500x1000, вы можете попробовать сжать изображение, если это то, что вам нужно.

Или вы можете использовать повторную выборку после захвата, чтобы уменьшить изображение. Одним из таких алгоритмов является бикубическая передискретизация, а также линейная передискретизация — существует множество вариаций.

Я думаю, это последнее, что вас больше всего интересует... в этом случае ознакомьтесь с этим Страница Википедии об алгоритме. Или вы можете перейти на сайт FreeImage и получить библиотеку, которая будет считывать изображения и изменять их размер.

person mmr    schedule 29.01.2009
comment
Спасибо за ваш вклад, но я ищу встроенные классы в ObjectiveC, которые могут служить цели. Нет времени писать алгоритмы с нуля. Спасибо. - person Mustafa; 29.01.2009

UIImageJPEGRepresentation делает свое дело, но я обнаружил, что использование фреймворка ImageIO часто дает значительно лучшие результаты сжатия при той же настройке качества. Это может быть медленнее, но в зависимости от вашего варианта использования это может не быть проблемой.

(Код адаптирован для NSData из этого сообщения в блоге Закари Уэста).

#import <MobileCoreServices/MobileCoreServices.h>
#import <ImageIO/ImageIO.h>

...

+ (NSData*)JPEGDataFromImage:(UIImage*)image quality:(double)quality
{
    CFMutableDataRef outputImageDataRef = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CGImageDestinationRef imageDestinationRef = CGImageDestinationCreateWithData(outputImageDataRef, kUTTypeJPEG, 1, NULL);

    NSDictionary* properties = @{
        (__bridge NSString*)kCGImageDestinationLossyCompressionQuality: @(quality)
    };
    CGImageDestinationSetProperties(imageDestinationRef, (__bridge CFDictionaryRef)properties);

    CGImageDestinationAddImage(imageDestinationRef, image.CGImage, NULL);

    CGImageDestinationFinalize(imageDestinationRef);

    CFRelease(imageDestinationRef);

    NSData* imageData = CFBridgingRelease(outputImageDataRef);
    return imageData;
}
person user2067021    schedule 13.07.2015