2012-06-19 48 views
11

尝试了解PNG格式。尝试从给定的PNG图像提取像素值

考虑这个PNG图片:

enter image description here

的影像从here

采取在十六进制编辑器,它看起来像这样:

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

同样示于以下的HEX编辑器的屏幕截图:

enter image description here

我试图反向工程此图像以提取所述报头部分和RGB像素值。我读了关于PNGhere,并且到目前为止我已经注意到以下关于此图像:

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 

下面我开始按顺序读取十六进制数据:

1-第一个8字节:这是8字节签名

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

相当于这是:%PNG可以在HEX编辑器中看到

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

2-组块:长度

00 00 00 0D 

3-组块:组块类型

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-块:BIT深度(1字节)

08 

7大块:颜色类型

02 

8压缩方法

00 

9-筛选方法:

00 

10隔行扫描法:

00 

11-什么是下面的数据?

C6 25 AA 3E 00 00 00 C2

12-- IDAT

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 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 96 ED 65 00 00 00 00

14- IEND:

49 45 4E 44

15-最后4个字节

AE 42 60 82 

这些是什么?

有些人可以帮助我理解上面的11,13和15点吗? Pixel值在哪里?该图像是具有(128×68像素)

知道这些细节的目的:

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

UPDATE

我现在明白了,因为压缩的,我不能够找到的像素值。

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

回答

3

尽管了解PNG图像的实际内容以及该图像在文件中如何表现出来可能很有趣,但您无需知道这将生成PNG文件。

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

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


如果你有灰度的16位像素值,那么你可以把它们放入一个Mat

然后再转换到IplImage结构:Converting cv::Mat to IplImage*

你可以把它输出到文件。

+0

我刚刚注意到有关压缩,所以它很好,我不会得到确切的像素值。但你能告诉我关于11和15吗? – gpuguy

+0

谢谢,你的回答对我很有帮助。我会测试它,然后发布结果。 – gpuguy

+3

+1但我不完全同意“你只是浪费了你的时间”。了解PNG的内部可能不是您目前的任务所必需的,但它仍然在学习。 – leonbloy

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。

3

我没看太仔细,但是从看结构...

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

Q13。 检查你之前提到的PNG规范,看起来像IDAT块,你已经知道应用于它的压缩!

Q15。 AE 42 60 82 = CRC32