13

试图理解PNG格式。

考虑这个PNG图像:

在此处输入图像描述

图片取自这里

在 Hex Editor 中,它看起来像这样:

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 80 00 00 00 44 08 02 00 00 00 
C6 25 AA 3E 00 00 00 C2 49 44 41 54 78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F 
B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 00 80 
00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 
00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 64 4B 94 F5 98 7C D1 F4 92 5C 5C 3E CF 9C 3F 
73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39 
C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00 
01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 37 DB 
68 03 20 FB ED 96 65 00 00 00 00 49 45 4E 44 AE 42 60 82

等效字符:

‰PNG........IHDR...€...D.....Æ%ª>...ÂIDATx^íÔ..Ã0.@Ñ·4Ýÿÿo³tVê‰.l(sâª4I.‡ÖþØ{‰
»R.;‡þ..€.......@....... ....€.......@....... ...Ô^jdK”õ˜|Ñô’\\>Ïœ?sqX_¯
‹y[î–¶GëñêÑζãu;湕.ÇÎ.9ɯÆ3“{f7Ï«¿ùÉ/.€.......@....... ....€.......@....... ..Œ7Ûh. 
ûí–e....IEND®B`‚

十六进制编辑器的以下屏幕截图中显示了相同的内容:

在此处输入图像描述

我正在尝试对该图像进行逆向工程以提取标题部分和 RGB 像素值。我在此处阅读了有关PNG的信息,到目前为止,我已经注意到有关此图像的以下内容:

IHDR 块必须首先出现。它包含:

Width:              4 bytes
Height:             4 bytes
Bit depth:          1 byte
Color type:         1 byte
Compression method: 1 byte
Filter method:      1 byte
Interlace method:   1 byte

下面我开始按顺序读取 HEX 数据:

1- 前 8 字节:这是 8 字节签名

 89 50 4E 47 0D 0A 1A 0A

等效地这是: %PNG 可以在 HEX 编辑器中看到

一个有效的 PNG 图像必须包含一个 IHDR 块、一个或多个 IDAT 块和一个 IEND 块。

2-块:长度

 00 00 00 0D

3-Chunk:Chunk 类型

 49 48 44 52

哪个是 IHDR。

http://www.w3.org/TR/PNG-Chunks.html

4- 块:图像的宽度(十进制 128)

00 00 00 80

5- 块:图像的高度(十进制 68)

00 00 00 44

6-块:位深度(1字节)

08

7-块:颜色类型

02

8- 压缩方法

00

9-过滤方法:

00

10- 交错法:

00

11-以下数据是什么?

C6 25 AA 3E 00 00 00 C2

12——IDAT

49 44 41 54

13- 这是什么数据(IDAT 之后):

78 5E ED D4 81 06 C3 30 14 40 D1 B7 34 DD FF FF 6F B3 74 56 EA 89 12 6C 28 73 E2 AA 34 49 03 87 D6 FE D8 7B 89 BB 52 8D 3B 87 FE 01 100 80 00 0 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 00 D4 5E 6A 54 4B 94 C 2C 54 4B 94 F 3E CF 9C 3F 73 71 58 5F AF 8B 79 5B EE 96 B6 47 EB F1 EA D1 CE B6 E3 75 3B E6 B9 95 8D C7 CE 03 39 C9 AF C6 33 93 7B 66 37 CF AB BF F9 C9 2F 08 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 20 00 00 20 00 00 20 00 00 20 00 00 20 00 00 01 00 20 00 00 04 00 80 00 00 10 00 00 02 00 40 00 00 08 00 00 01 00 20 00 00 8C 0 0 37 DB 96 6 00 00

14- IEND:

49 45 4E 44

15- 最后 4 个字节

 AE 42 60 82

这些是什么 ?

有人可以帮助我理解上面的第 11、13 和 15 点吗?像素值在哪里?图像具有(128 x 68 像素)

了解这些细节的目的:

一旦我知道了这些细节,我将生成我自己的 16 位 PNG 图像。我已经有了像素值,所以我的工作是引入标题等。
我不知道是否有软件可以执行这项工作。

更新

我现在明白由于压缩,我无法找到像素值。

我想到我可以在 OpenCV 中编写一个文件并将其保存为 png。那么现在我的直接问题是:我有一个具有灰度 16 位像素值的二进制文件。我可以在 OpenCV 中将其写为 16 位 PNG 吗?

4

3 回答 3

4

尽管了解 PNG 图像实际上是什么以及图像在文件中的实际表示方式可能会很有趣,但您无需知道这些即可生成 PNG 文件。

请注意,PNG 使用无损压缩,这意味着每个像素不会得到两个字节。

您可以使用现有的许多库在程序中生成图像并以 PNG 格式输出。例如,您可以在 OpenCV 中制作图像,然后使用imWrite. 其中一个参数可以使其输出到 PNG。


如果您有灰度 16 位像素值,则可以将它们放入Mat.

然后将其转换为 IplImage:Converting cv::Mat to IplImage*

然后,您可以将其输出到文件中。

于 2012-06-19T11:58:49.110 回答
3

只是为了完整性(eboix的回答当场就对了)

11-以下数据是什么?

C6 25 AA 3E 00 00 00 C2

每个块以CRC(4 个字节)结束,并以 4 个字节开始,告诉它的长度。因此,C6 25 AA 3E是前一个块 (IHDR) 的 CRC,而00 00 00 C2(194) 是下一个 (IDAT) 块的长度。

同理,最后 4 个字节是 IEND 块的 CRC。

于 2012-06-19T13:53:34.093 回答
3

我没有仔细看,而是从结构上看...

问题 11。C6 25 AA 3E = CRC32 00 00 00 C2 = 下一个块的大小

问题 13。检查您之前提到的 png 规范,它看起来像您已经知道应用到它的压缩的 IDAT 块!

问题 15。AE 42 60 82 = CRC32

于 2012-10-23T21:02:51.957 回答