2014-10-19 4 views
3

Глядя на PNG specification, кажется, что блок данных пикселя PNG начинается с IDAT и заканчивается IEND (немного более ясное объяснение here). В середине есть значения, которые не имеют смысла иметь смысл для меня.Интерпретировать данные пикселя PNG

Как я могу получить полезные значения RGB из этого, без использования каких-либо библиотек (т.е. из необработанного двоичного файла)?

В качестве примера, я сделал 2x2px изображение с 4 черными rgb(0,0,0) пикселями в Photoshop:
Just four black pixels...

Вот полученные данные (в сыром двоичном входе, значения шестигранных и читаемый ASCII) :

BINARY  HEX ASCII 
01001001 49 'I' 
01000100 44 'D' 
01000001 41 'A' 
01010100 54 'T' 
01111000 78 'x' 
11011010 DA '\xda' 
01100010 62 'b' 
01100000 60 '`' 
01000000 40 '@' 
00000110 06 '\x06' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
11111111 FF '\xff' 
11111111 FF '\xff' 
00000011 03 '\x03' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00001110 0E '\x0e' 
00000000 00 '\x00' 
00000001 01 '\x01' 
10000011 83 '\x83' 
11010100 D4 '\xd4' 
11101100 EC '\xec' 
10001110 8E '\x8e' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
00000000 00 '\x00' 
01001001 49 'I' 
01000101 45 'E' 
01001110 4E 'N' 
01000100 44 'D' 

ответ

6

Вы пропустили довольно важную деталь в обеих спецификациях:

официальный один:

.. Блок IDAT содержит фактические данные изображения, которые являются выходным потоком алгоритма сжатия.
[...]
Сжатые с давлением потоки данных в PNG хранятся в формате "zlib".

Википедия:

IDAT содержит изображение, которое может быть разделено между несколькими кусками IDAT. Такое расщепление увеличивает размер файла немного, но дает возможность генерировать PNG потоковым способом. Блок IDAT содержит фактические данные изображения, который является выходным потоком алгоритма сжатия.

Оба состояния данных необработанного изображения: сжато. Глядя на ваши данные, то первые 2 байта

78 DA 

содержат флаги сжатия, как указано в RFC1950. Остальные данные сжимаются.

Декомпрессия это с общей zlib совместимой рутинного шоу 14 байт выхода:

00 00 00 00 00 00 00 
00 00 00 00 00 00 00 

, где каждый первый байт в PNG фильтр строк (0 для обоих рядов), а затем 2 RGB триплетов (0,0 , 0), для 2 строк вашего изображения.

«без использования каких-либо библиотек», вам нужно 3 отдельных подпрограмм для:

  1. чтения и разбора надстройку PNG; это обеспечивает сжатые данные IDAT, а также необходимую информацию, такую ​​как ширина, высота и глубина цвета;
  2. распаковать zlib часть (ы) в необработанные двоичные данные;
  3. проанализировать декомпрессированные данные, обработать смену Adam-7, если необходимо, и применить фильтры строк.

Только после выполнения этих трех шагов вы получите доступ к необработанным данным изображения. Из них вы, кажется, хорошо понимаете шаг (1). Шаг (2) намного сложнее «сделать»; лично я обманул и использовал miniz в своих собственных программах обработки PNG. Шаг 3, опять же, является просто вопросом определения. Все необходимые биты информации можно найти в Интернете, но требуется некоторое время, чтобы все было в правильном порядке. (Совсем недавно я обнаружил ошибку в моем исполнении редко используется строка фильтра Paeth - он остался незамеченным, потому что она довольно редко используется в «реальном мире» изображений.)

См Building a fast PNG encoder issues для подобного обсуждения и Trying to understand zlib/deflate in PNG files для углубленного изучения схемы Deflate.

+0

Очень, очень полезно - спасибо! – JeffThompson

Смежные вопросы