Уменьшите размер UIImage до управляемого размера (уменьшите байты) - PullRequest
9 голосов
/ 28 января 2009

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

Ответы [ 5 ]

23 голосов
/ 30 января 2009

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

NSData *dataForPNGFile = UIImagePNGRepresentation(yourImage);

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

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

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

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

11 голосов
/ 06 марта 2010

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

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

1 голос
/ 28 января 2009

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

0 голосов
/ 13 июля 2015

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;
}
0 голосов
/ 29 января 2009

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

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

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

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

...