png文件结构解析
一直在了解前端二进制,想找个简单的入手,于是就先从前面canvas生成的png开始吧,先开始了解png的结构吧。
一、准备
我用的时VS Code,提前下了hexdump for VSCode,该插件可以查看文件的二进制信息。
二、png结构解析
数据块结构
PNG图像格式文件由一个8字节的PNG文件署名域和按照特定结构组织的3个以上的数据块(chunk)组成。
数据块又分为两种类型,关键数据块和辅助数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们。
数据块的4个域组成如下:
在同一张表下显示关键和辅助数据,其中带前下划线的是关键数据块,其他的是辅助数据块:
关键数据块的组成如下:
- IHDR,文件头数据块,他描述了图像数据的基本信息,一个PNG数据流中只能有一个文件头数据块。
他的格式如下:
- PLTE,调色板数据块,该数据块是定义图像的调色板信息,PLTE可以包含1~256个调色板信息,每一个调色板信息由3个字节组成。
- IDAT,图像数据块,他存放着图像真正的数据信息,在数据流中可包含多个连续顺序的图像数据块。
- IEND,图像结束数据,他描述了PNG文件或者数据流已经结束,并且必须要放在文件的尾部。
PNG格式有8位、24位、32位三种形式,其中8位PNG支持两种不同的透明形式(索引透明和alpha透明),24位PNG不支持透明,32位PNG在24位基础上增加了8位透明通道,因此可展现256级透明程度。
PNG8和PNG24后面的数字则是代表这种PNG格式最多可以索引和存储的颜色值。”8″代表2的8次方也就是256色,而24则代表2的24次方大概有1600多万色。
实例解析
看例子会比较更容易理解,在vs code中使用插件打开一张png图片,先看下头部区域,
89 50 4E 47 0D 0A 1A 0A,是png文件署名域,表示这是一个png图片。
00 00 00 0D,描述了IHDR的大小,十六进制的0D转成十进制就是13,所以在IHDR后13个字节是描述存储图像的基本信息的。对着前面的表格,我们就知道这是张60*60(3C*3C)的图,除了onload图片获取宽高,是不是又多了种方法了? 紧接着后面的4个字节是对IHDR的CRC校验码,即B5 9E 4E 25。 后面就是辅助数据块pHys数据块了。
在末尾的IEND关键数据块,最后的AE 42 60 82是他的CRC校验码。因为IEND数据块的长度总是0(00 00 00 00),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82,除非我们自己添加了数据。
IDAT
60*60图太大了,简单起见,改用3*3的一张图。
按照块的定义,第一部分的4个字节是描述该块内容大小的,1f转成十进制是31,跳过4个字节的数据块名,被蓝色框选中的就是该png的数据内容,最后30 69 E4 17则是CRC校验码。 由于这块数据采用了LZ77派生算法,所以不能直接看出对应的数据,后面也将研究下这块算法。
参考:
https://www.jianshu.com/p/4d8cace82028
https://blog.csdn.net/kk1751413376/article/details/50764653