国米preT PNG像素数据 [英] Interpret PNG pixel data

查看:235
本文介绍了国米preT PNG像素数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

纵观 PNG规范,现在看来,PNG像素数据块开始与 IDAT IEND 结尾(略更清楚的解释的这里)。在中间值是没有意义的道理给我。

我怎样才能从这个有用的RGB值,而无需使用任何库(即从原始的二进制文件)?

作为一个例子,我做了一个形象2x2px与4黑色 RGB(0,0,0)在Photoshop像素:结果

下面是所产生的数据(在原始的二进制输入,十六进制值,和人类可读的ASCII):

 二进制十六进制ASCII
01001001 49'I'
01000100 44'D'
01000001 41'A'
01010100 54'T'
01111000 78的x
11011010 DA'\\ XDA
01100010 62'B'
01100000 60'''
40 01000000@
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'\\ XD 4'
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'


解决方案

您错过了两个规格的,而关键的细节:

官方之一:


  

..的IDAT组块包含实际的图象数据也就是玉米pression算法的输出流。结果,
  [...]结果
  内的PNG放气泡沫pressed数据流被存储在ZLIB的格式。


百科:


  

IDAT包含图像,其可以多个IDAT组块之间被分割。这种分裂增加文件大小略有下降,但使得能够产生在一个流式方式一个PNG。的IDAT组块包含实际的图象数据,它是玉米pression算法的输出流。


这两种状态的原始图像数据的 COM pressed 的。看你的数据显示,前2个字节

  78 DA

包含在 RFC1950 指定的COM pression标志。该数据的其余部分是COM pressed。

DECOM $ P $与一般的zlib 兼容常规节目14个字节的输出pssing这

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

每个第一个字节(两行0),PNG行筛选,其次是2 RGB三胞胎(0,0,0),对于两行的形象。

没有使用任何库你需要3个独立的程序为:


  1. 读取和解析PNG上层建筑;这提供了 IDAT COM pressed数据,以及诸如宽度,高度和颜色深度的基本信息;

  2. DECOM preSS的的zlib 部分(S)为原始二进制数据;

  3. 解析DECOM pressed数据处理(如果需要)亚当 - 7交错和应用行筛选器。

仅在执行这三个步骤之后,你将有机会获得的原始图像数据。这些,你似乎有步骤(1)把握好。步骤(2)是路难做自己;就个人而言,我被骗了,并使用 miniz 我自己的PNG处理程序。第3步,再次是仅仅的确定的一个问题。所有必要的信息比特可以在网络上找到,但它需要一段时间才能把一切都在正确的顺序。 (就在最近,我在很少使用Paeth行筛选的执行发现错误 - 它去忽视的,因为的这是相当罕见的真实世界的图像使用。)

请参阅构建快速PNG连接codeR问题对类似的讨论和<一个href=\"http://stackoverflow.com/questions/26018811/trying-to-understand-zlib-deflate-in-png-files\">Trying要了解的zlib /放气的PNG文件一个深入了解入放气方案。

Looking at the PNG specification, it appears that the PNG pixel data chunk starts with IDAT and ends with IEND (slightly clearer explanation here). In the middle are values that don't make sense to make sense to me.

How can I get usable RGB values from this, without using any libraries (ie from the raw binary file)?

As an example, I made a 2x2px image with 4 black rgb(0,0,0) pixels in Photoshop:

Here's the resulting data (in the raw binary input, the hex values, and the human-readable 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'

解决方案

You missed a rather crucial detail in both the specifications:

The official one:

.. The IDAT chunk contains the actual image data which is the output stream of the compression algorithm.
[...]
Deflate-compressed datastreams within PNG are stored in the "zlib" format.

Wikipedia:

IDAT contains the image, which may be split among multiple IDAT chunks. Such splitting increases filesize slightly, but makes it possible to generate a PNG in a streaming manner. The IDAT chunk contains the actual image data, which is the output stream of the compression algorithm.

Both state the raw image data is compressed. Looking at your data, the first 2 bytes

78 DA

contain the compression flags as specified in RFC1950. The rest of the data is compressed.

Decompressing this with a general zlib compatible routine show 14 bytes of output:

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

where each first byte is the PNG row filter (0 for both rows), followed by 2 RGB triplets (0,0,0), for the 2 lines of your image.

"Without using any libraries" you need 3 separate routines to:

  1. read and parse the PNG superstructure; this provides the IDAT compressed data, as well as essential information such as width, height, and color depth;
  2. decompress the zlib part(s) into raw binary data;
  3. parse the decompressed data, handling Adam-7 interlacing if required, and applying row filters.

Only after performing these three steps you will have access to the raw image data. Of these, you seem to have a good grasp of step (1). Step (2) is way harder to "do" yourself; personally, I cheated and used miniz in my own PNG handling programs. Step 3, again, is merely a question of determination. All the necessary bits of information can be found on the web, but it takes a while to put everything in the right order. (Just recently I found an error in my execution of the rarely used Paeth row filter--it went unnoticed because it is fairly rarely used in 'real world' images.)

See Building a fast PNG encoder issues for a similar discussion and Trying to understand zlib/deflate in PNG files for an in-depth look into the Deflate scheme.

这篇关于国米preT PNG像素数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆