便携式网络图形(PNG)规范(第二版)
当前版本:工作字节顺序)。
目前主机常用的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)。
后面的公式太复杂,算了,直说。