Я хочу уменьшить количество байтов изображения, захваченного устройством, так как я считаю, что _imageScaledToSize
не уменьшает количество байтов изображения (или уменьшает?) - я хочу сохранить миниатюру изображения в локальном словарь и не может позволить себе помещать в словарь полноразмерные изображения. Есть идеи?
Уменьшите размер UIImage до управляемого размера (уменьшите байты)
Ответы (5)
Если вы хотите просто сжать свой UIImage, вы можете использовать
NSData *dataForPNGFile = UIImagePNGRepresentation(yourImage);
для создания версии NSData вашего изображения, закодированного как PNG (легко вставленного в NSDictionary или записанного на диск), или вы можете использовать
NSData *dataForPNGFile = UIImageJPEGRepresentation(yourImage, 0.9f);
сделать то же самое, только в формате JPEG. Второй параметр — качество изображения JPEG. Оба они должны создавать изображения, которые меньше по объему памяти, чем ваш UIImage.
Изменение размера UIImage для создания миниатюры меньшего размера (в пикселях) с использованием опубликованных методов немного сложнее. _imageScaledToSize — это частный API, и я настоятельно рекомендую вам не использовать его. Чтобы узнать о способах, которые работают в рамках задокументированных методов, см. эту публикацию.
Я столкнулся с этой проблемой на днях и провел довольно много исследований. Я нашел отличное решение с кодом здесь:
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
UIImage
, которая не страдает от этой проблемы.
- person Rob; 05.02.2014
Вам нужно нарисовать изображение в графическом контексте меньшего размера. Затем отпустите исходное изображение.
Когда вы говорите «физический размер», вы имеете в виду отпечаток? Потому что вы можете просто изменить размер страницы принтера.
Вы говорите о количестве пикселей, используемых для захвата изображения? Например, если у вас есть массив пикселей 3000x2000, а вам нужен только размер 150x150, вы можете обрезать изображения. Во время захвата, если у вас есть научный тепловизор, вы можете просто установить область, которая будет захвачена. Драйвер камеры будет содержать инструкции для этого. Если вы хотите захватить 3000x2000 в 1500x1000, вы можете попробовать сжать изображение, если это то, что вам нужно.
Или вы можете использовать повторную выборку после захвата, чтобы уменьшить изображение. Одним из таких алгоритмов является бикубическая передискретизация, а также линейная передискретизация — существует множество вариаций.
Я думаю, это последнее, что вас больше всего интересует... в этом случае ознакомьтесь с этим Страница Википедии об алгоритме. Или вы можете перейти на сайт FreeImage и получить библиотеку, которая будет считывать изображения и изменять их размер.
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;
}