Пользовательский формат изображения: как настроить алгоритмы сжатия - PullRequest
1 голос
/ 24 февраля 2012

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

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

Большинство изображений, с которыми я работаю, - это PNG-8bpp с полной 256-цветовой палитрой. Большинство этих изображений я мог бы точно представить с 5bpp (32 цвета).

PNG проиндексирован, однако поддерживает только 1,2,4 и 8bpp. Поэтому моя идея заключалась в том, чтобы сократить формат PNG до минимума, который мне требовался, и написать кодер / декодер для поддержки секций IDAT с 3,5,6 или 7 бит / с.

Test 1:
Original File: 61.5KB, 750 * 500, 8pp Palette, 256 colors, No tRNS
After Optimizations (Reductions to 4bpp, Strip Anx Chunks, & PNGOUT): 49.2KB 4bpp, 16 Colors
Human Interpretation: I can see 6 distinguishable colors.

Поскольку для представления изображения мне нужно всего шесть цветов, я решил закодировать IDAT с использованием 3bpp, чтобы получить максимальную палитру из 8 цветов. Сначала я распаковал IDAT, что привело к новому размеру файла 368 КБ. После применения 3bpp к IDAT размер моего нового несжатого файла составляет 274 КБ. Я пошел к тому, что казалось хорошим началом ... Затем я применил deflate к своему новому разделу IDAT. Результат ... 59КБ.

10KB больше, чем при использовании 4bpp.

Test 2:
Original File: 102KB, 1000 * 750, 8bpp, 256 Colors, tRNS 1 fully transparent color
After Optimization: 79KB, 8bpp, 193 colors, tRNS 1 full transparent color
Human Interpretation: I need about 24 colors to represent this picture.

24 цвета могут быть представлены в 5bpp на 32 цвета. Используя ту же технику, описанную выше, я смог добиться гораздо лучших результатов по сравнению с несжатыми, но снова потерял при сжатии. Окончательный размер сжатый ... 84KB. Затем я попытался на 6,7bpp ... Сжатие с тем же результатом, что и на 8bpp.

Просто чтобы быть уверенным, что я сохранил все несжатые изображения и попробовал несколько других алгоритмов сжатия ... LZMA, BZIP2, PAQ8 ... тот же результат, меньший размер сжатия на 8bpp, чем на 5,6, или 7bpp И меньший размер на 4bpp чем при 3bpp.

Почему это происходит? Могу ли я настроить / изменить алгоритм сжатия для целевого формата, подобного PNG, который использует формат 5,6 или 7bpp, обеспечивающий сжатие 8bpp? Стоит ли это времени ... и да, сохранение еще 10 КБ будет стоить.

Ответы [ 2 ]

2 голосов
/ 26 февраля 2012

То, что вы видите, заключается в том, что при использовании нечетных размеров пикселей ваше эффективное сжатие уменьшается из-за того, как работает сжатие PNG.Преимущество сжатия PNG над простым использованием сжатия FLATE / ZIP заключается в фильтрации.Сжатие PNG пытается использовать горизонтальную и вертикальную симметрию с небольшим ассортиментом фильтров предварительной обработки.Эти фильтры работают на байтовых границах и эффективны с размерами пикселей 4/8/16/24/32/48/64 бит.Когда вы переходите к пикселю нечетного размера (3/5/6/7 бит), вы подавляете фильтрацию, потому что идентично окрашенные пиксели не будут «гасить друг друга» по горизонтали при фильтрации на 8-битных границах.

Даже если фильтрация не была проблемой, то, как работает сжатие FLATE, уменьшение размера пикселя с 8 до 7 или 6 битов также не будет иметь большого эффекта, поскольку оно также предполагает размер символа 8-bits.

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

Сжатие GIF поддерживает все размеры пикселей от 1 до 8 бит.Он определяет размер символа как размер пикселя и не использует никакой предварительной фильтрации.8-битное изображение GIF, если оно будет сжато как 7-битные пиксели, не будет испытывать меньшего сжатия, но также не выиграет, потому что сжатие зависит больше от повторения пикселей, чем от размера символа.

0 голосов
/ 07 марта 2013

Сжатие DEFLATE, используемое PNG, имеет два основных метода:

  • находит повторяющиеся последовательности байт и кодирует их в виде обратных ссылок
  • кодирует байты с использованием кодирования Хаффмана

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

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

...