便携式网络图形(PNG)规范(第二版)

W3C于2003年6月165438+10月10正式推荐。

当前版本:工作字节顺序)。

目前主机常用的X86和ARM处理器都是小端模式,称为主机字节序。

PNG使用网络字节顺序。

普通真彩色图片至少由红、绿、蓝三个通道组成,即每个像素占用三个字节以上的空间。所以图片的压缩效率很低。

所以我们构建一个调色盘,在调色盘中预置我们需要使用的颜色,只需要提供调色盘的索引位置,供后续使用。

而且为了防止调色板占用太多空间,我们把调色板的容量设置在256以内。索引位置不会超过256,只需要一个字节来表示,一个字节只占用一个通道,所以索引模式只有一个通道。

一张图片是由很多像素组成的,可以看作一个二维数组。我们可以提取几个特殊的位置,比如水平行的每隔一个像素,垂直列的每隔一个像素,这样就形成了一个新的二维数组,可以简洁而失真地表示原始图像。这种提取方式称为Pass提取,提取后形成的数据是交错的,每一段都可以包含整张图片的缩略图。只需要重新组合产生一个完整的图像,即使没有完整的数据,只要其中的一部分就可以得到缩略图。是网络传输中加快图像传输的一种方式,但是现在网速太快了,几乎没有用。

色卡中间区域为白色,我们称之为白点,是色卡的一个参数。另一个参数是基准,用于颜色映射的转换。

我们可以通过设置白点的坐标来改变中间的白色区域,使其向红绿蓝偏移,从而调整彩色地图的变化程度。

PNG规范没有规定应用程序接口,但是涉及到四种图像:原始图像、标准图像、PNG图像和交付图像。这种关系如下:

二进制编码占用的位数就是样本深度。

PNG有三种方式管理色彩空间:ICC配置、sRGB配置、色度参考和白点位置配置。

ICC配置灵活,易于适配;SRGB配置需要设置特定的色彩空间,可能会占用更多的容量;最后一个更准确。对于前两个,也建议使用Gamma值。

我们需要一些方法将标准图像转换成PNG图像。流程如下:

分离透明通道,其实很多标准图像都没有透明通道,可以默认为不透明,省了一个通道。

如果不同像素值的数量小于256,并且样本深度小于或等于8,则可以建立索引。

如果颜色样本的深度相同,并且每个通道具有相同的值,则一个通道可以用来表示所有内容,即灰度图像。

一种不用alpha通道表示透明度的方法,需要设置背景色。

PNG并不支持所有深度,只支持1,2,4,8,16。如果不是这些数字,深度必须由软件调整。

比如原来的深度是5,现在要改成8,也就是扩大了。

如果不同的通道深度不同,我们会选择最大深度进行调整。

这种深度转换是可逆的。

有五种* * *:

这里,使用两种方法来提取Pass。

第一种是空方法,意思是什么都不做。(那为什么这么死板的把这个算作方法呢?)

在第二种方法中,通过多次扫描获得七个缩减的图像。也就是Adam7算法(不是深度学习的Adam算法)。

但是这个算法在国内网站上几乎找不到,从维基百科(https://en . Wikipedia . org/wiki/Adam 7 _ algorithm)上也不是很清楚。所以我在这里就简单说一句:

把上面的缩小图(当然原图是用空的方法读的)一行一行的读一遍。(这里可以有很多操作,比如把上面的提取转化为产量。)

有几种过滤器类型,将在过滤器数组之前编写。

是编码和加密。

将编码数据分成一个或多个块。

一个标准的PNG文件由许多块组成,每个块有四个部分:长度、名称、数据体和校验码。

标准PNG定义有18个块类型,您可以添加自定义块。

这些18块类型是:

关键块:

IHDR(图像头文件头),PLTE(调色板调色板),IDAT(图像数据图像内容),IEND(图像结束文件结束)。

辅助块:

透明关联:透明信息

色彩相关性:chrm(色度和白点)、gAMA(伽玛伽玛值)、iCCP(嵌入式ICC配置文件嵌入式ICC概述)、sBIT(有效位)、sRGB(标准RGB色彩空间)。

文本相关:iTXt(国际文本数据国际化文本),Text(文本数据文本),zTXt(zip文本数据压缩文本)。

时间相关性:时间(上次修改时间)

其他:bKGD(背景色),hIST(直方图),pHYs(物理像素尺寸),sPLT(建议调色板),

传输错误或文件损坏,这将破坏大部分或全部数据流;语法错误,无效块或丢失块。

应该区分这两种错误处理方法。

可以向ISO/IEC或PNG组提交相关扩展,注册新的块类型和文本关键字,扩展新的过滤算法、交错模式算法和压缩算法。

它是数据流的二进制结构。

所有PNG数据流的前八个字符是137 80 78 78 7131026 10。

Bytes表示b'\x89PNG\r\n\x1a\n '

这个签名表示后面的数据都是PNG数据流。如果你遇到空字符,不要打断他们,你需要IEND来完成。

每个模块由以下四部分组成:

通过名称约定,PNG解码器在无法识别当前块的用途时,可以通过名称获取相关信息。

块的名称有四个数字:

第一位表示辅助,小写表示这个块是辅助,大写表示这个块是关键。

第二位数字表示私有,小写表示这个块是私有的,没有国际标准定义,大小表示前面提到的18块类型。

第三位是保留位,小写表示该块被丢弃,大写表示可以使用。(用于商定未来的扩展)

第四位表示复制安全,即在编辑图片时,如果PNG编辑器遇到不安全的数据块,不会完全复制,而是选择性复制。大写意味着PNG编辑器可以完全复制而不用担心任何问题。

详见crc32算法。

因为PNG图像可以流式传输,也就是说,它们可以在PNG浏览器中预览,而无需读取文件的结尾。

所以在读取图像内容之前需要准备一些东西,比如索引调色板。

好像已经写到4.3章了?

正如我们在第4.4章中所写的,有五种颜色类型:

颜色类型记录在IHDR。

在灰色模式,亮度取决于伽马,sRGB,iCCP,如果不是,它取决于机器。

颜色样本不一定与光线强度成比例,可以通过设置gAMA来调整。

值的计算方法如下:初始为0,使用调色板加1,使用真彩色加2,使用透明通道加4。灰度中不能使用索引。

透明度有四种表达方式:使用透明通道,用tRNS块设置透明颜色信息,在索引中的tRNS中设置alpha表,不使用透明通道或tRNS表达完全不透明。

透明通道的采样深度为8和16,透明通道存储在像素中,表示完全透明和完全不透明。透明度用于组合图像的前景色和背景色。

有些普通图片不含透明度,甚至像素值已经乘以透明度,提前做了与黑色背景的复合步骤;但是巴布亚新几内亚不这样做。

Integer (int)是多字节的,short是2,int是4,long是8。

PNG使用网络字节顺序,MSB在高位,LSB在低位。

即,每个PNG图像的行和像素被紧凑地排列。

当深度小于8时,扫描线的末端可能是不匹配的字节,这些未使用的字节将不会被处理。

过滤器可以提高压缩数据的可压缩性,并且是可逆的。PNG允许对扫描线数据进行过滤,换句话说,不过滤也可以过滤。

过滤后的字节序列与过滤前相同,但根据不同的过滤类型,会在前面增加一个字节标记。如果长度没有增加,说明没有过滤。具体的过滤方法将在后面说明。

隔行模式可以提高网络图片在CRT显示器上的加载速度(换句话说,没有网络和CRT显示器,隔行模式是没有用的)。

请参考[4.5.2通道提取](#4.5.2通道提取)

由于Adam7的特性,宽度或高度小于5的图像会缺少缩略图(第五列2个,第五行3个)。

过滤的目的是提高压缩比。过滤的方法不是唯一的。在隔行模式下,所有缩小的图像应该使用相同的过滤器。在非交错模式下,只有一张图片,当然也只有一种方法。

本标准中定义了方法0,其他数字留待将来使用。方法0包含五种类型的过滤器,每条扫描线可以使用不同的过滤器类型。

PNG规范并不强制要求滤镜的类型,具体的选择方法将在后面讨论。

该过滤器适用于字节,不考虑像素、通道和深度。只要给字节就可以过滤。

以下是几个参数的定义:

Org()表示字节的原始值;

Flt()表示筛选后的值;

Rc()表示重构值;

Paeth()参见[9.4过滤器类型4](#9.4过滤器类型4)。

如果没有前一个像素,则使用0。每个缩略图的第一行没有上一行,也用0代替。

因为使用了滤波,所以重建也应该按照这个顺序来计算。

过滤器的输入和输出值都是无符号字节。

0,1,2三类滤波器都很简单,就是交替列/隔行减法。

但在第三种类型中,FLT(x)= Org(x)-floor((Org(a)+Org(b))/2),Org(a)+Org(b)溢出,所以不能使用字节运算,应该是短位或多位。当然还有右移的算法。

Paeth算法首先计算三个相邻像素(左、上、左)的线性值,然后选择与计算值最接近的相邻像素重新计算。注意不要溢出缓存。其功能如下:

和上面的过滤一样,默认是方法0。这两个在IHDR有标记。

当然这里用的是zlib压缩,默认级别是8,压缩的字节不超过32768。

这个校验值和PNG块的校验值不同,不能混淆。

将多个过滤后的行打包压缩成一个zlib数据流,放入多个PNG块,多个PNG块解包得到一个zlib数据流。

当然,这也涉及到异步读取。Zlib数据流本身是可以被中断的,即使被中断,仍然可以读出之前排列的数据,从而可以解释交错的图案。因此,对于上面的python方法,进行了以下改进:

建立一个连续的阅读,阅读和解析。

以下是18 PNG规格块的介绍:

IHDR是PNG数据流中的第一块。组成如下:

所以IHDR的块长度是13,不会改变。

调色板是一个二维数组,可以看作Array[n][3],颜色用index n表示。

所以n不会超过256,PLTE块的长度也是3的倍数。

在任何情况下,调色板都是8位深。即使图像是1,2,4,调色板还是8。

所有IDAT块合在一起就是一个zlib数据流,参见[10压缩](#10压缩)。

这段数据为空,表示PNG数据流结束。当然这个块损坏了就没事了。

这是一个表示透明度信息的块,它有三个组成部分:

灰度模式(任何等于该灰度的颜色都被认为是透明的)

真彩色模式(透明色由这三个值表示)

索引模式(在索引模式下,tRNS相当于一个alpha表,和索引一样大,表示索引的透明性)

为什么灰度模式和真彩色模式用2个字节表示?因为它需要适应16位的深度,而索引模式的深度总是小于等于8。

该模块用于设置CIE色度空间。组成如下:

存储值是实际值的100000倍。

CIE色度空间是一个二维图像,由红、绿、蓝、白四个点构成一个近视三角形来设置颜色偏差的程度。

这个块只存储一个无符号的int,它的值需要除以100000才能得到实际的gamma值。

该块用于设置ICC描述。

PNG仅支持固定深度。如果和原图深度不符,会被强制放大缩小,但这里会保留原始信息,恢复原图。(所以一般不用。为什么要把标准图像转换成非标准图像?)

不同的信道号有不同的sBIT长度。

使用sRGB颜色空间,它现在不能被ICC描述。SRGB只包含一个无符号字节,表示渲染意图。

该值的含义如下:

使用sRGB时推荐使用GAMA和cHRM,因为有些设备不支持sRGB,所以可以兼容使用。

以上是文字信息中会用到的关键词。关键词其实不是很关键,只是一个定义,可以自己改。但是可以通过图像软件标准读取。

文本包含以下组件:

当然这里的压缩方式也是0,用zlib来解压后面的数据。

国际文本数据有点高。

有关语言类型,请参见RCF-3066、ISO 646和ISO 639。

背景颜色。

直方图给出了调色板中每种颜色的大致使用频率。

如果PNG浏览器不能提供调色板中的所有颜色,直方图可以帮助创建类似的调色板。

当然,没有软件不能提供完整的调色板。

该块用于表示屏幕上像素的实际大小。其结构如下:

有两个单元描述。如果为False,则表示该块仅代表长宽比,而不是真实值。True时以米为单位,即一个单位是一米,一米包含多少像素。

具体的通道长度由样品的深度决定。16的深度是二,小于等于8是一。

调色板名称区分大小写,受关键字参数的限制。

在灰度PNG图像中,每个目的地通常具有相等的红色、绿色、蓝色和蓝色值,但这不是必需的。

每个频率值与图像中像素的比例成比例,而不是实际频率。

这里使用世界时(UTC)。

后面的公式太复杂,算了,直说。