Качество сжатия JPEG с использованием CGImage

Im использует API CGImage (CGImageDestination, CGBitmapContext,, CGImage и т.д.) в Mac OS X, а также iOS для сжатия изображений в формате JPEG. Используя свойство kCGImageDestinationLossyCompressionQuality, вы можете контролировать качество сжатия: 0.0 максимальное сжатие и 1.0 - максимальное качество (без потерь, если это возможно, согласно Apple).

Ive обнаружил, что theres огромный скачок как размера диска, так и качества изображения при переходе от 0.99 до 1.0. Например, Ive получил изображение 2048x1368, которое сжимается до 430 КБ, когда для качества установлено значение 0.99 но воздушные шары до 2,3 МБ, когда качество установлено на 1,0. Theres большой скачок в визуальном качестве, а настройка 0.99 не подходит для этого конкретного изображения. Попытка установить качество на что-либо между 0.99 до 1.0 не работает, так как размер остается на уровне 430 КБ до 0.995, где он вскакивает до 2,3 МБ. Кроме того, на самом деле разница между качествами 0.90 до 0.99 действительно невелика, которая варьируется в размере файла от ~ 353 КБ до 430 КБ, но не намного улучшает качество изображения.

Кто-нибудь знает, есть ли способ увеличить качество JPEG? Мне действительно нужно что-то лучшее, чем 0.99 дает мне меньше, чем 1.0. Может быть, какой-нибудь другой API, который я мог бы использовать?

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

Update

После некоторого исследования выясняется, что для всех kCGImageDestinationLossyCompressionQuality настроек до 1.0 Apple использует 4: 2: 0 цветовоспроизведение цвета (или прореживание цветности). Это означает, что для изображения YCrCb они выбирают только один цветной пиксель (CrCb) для каждых 4 пикселей яркости (Y). Другими словами, они используют только 1/4 данных цветности от исходного изображения. Для качества 1.0 Apple использует 4: 4: 4 цветную подвыборку, которая не является поддиапазоном цветности или одним цветным пикселем для каждого пикселя яркости. Вот почему размер файла взрывается, поскольку изображение содержит 4x данных о цвете и качествах <= 0.99.

Итак, кто-нибудь знает, есть ли способ отключить передискретирование цветности с использованием CGImage (или любого другого API) для качеств менее 1.0?

Ответы

Ответ 1

Окончательное обновление

После обширных исследований и последующих предложений в комментариях выше, кажется, что невозможно отключить передискретизацию/децимацию цветности с любым из встроенных API-интерфейсов Яблока, не устанавливая kCGImageDestinationLossyCompressionQuality в 1.0, что приводит к очень большому изображений.

Если вам нужно контролировать самовосстановление/прореживание цветности самостоятельно при сохранении в формате JPEG, вам необходимо использовать стороннюю библиотеку, такую ​​как libjpeg.

Ответ 2

Может быть, какой-нибудь другой API, который я мог бы использовать?

WebP - это новый формат изображения от Google, который дает лучшее сжатие, чем jpg и png, как без потерь, так и с потерями. Существует проект github, который довольно прост в использовании: https://github.com/seanooi/iOS-WebP

Вы просто добавляете категорию и среду WebP в свой проект, чтобы использовать ее.

//Converting To WebP
// quality value is [0, 100]
NSData *webpData = [UIImage imageToWebP:[UIImage imageNamed:@"image.jpg"] quality:75];

//Converting From WebP
UIImage *webPImage = [UIImage imageFromWebP:@"/path/to/file"];

//Setting image transparency
//alpha value is [0, 1]
UIImage *transparencyImage = [[UIImage imageNamed:image.jpg] imageByApplyingAlpha:0.5];

Альфа работает неправильно, но поскольку вы используете jpg, я предполагаю, что вам это не нужно.