跳转到内容

分形/png

来自维基教科书,开放世界中的开放书籍

PNG 特性

  • 对于 png,颜色深度范围可以从每像素 1 比特到 64 比特
  • 所有 PNG 图像都包含单个静态图像
  • 1、2、4 和 8 比特调色板支持(如 GIF)
  • 1、2、4、8 和 16 比特灰度支持
  • 8 比特和 16 比特每样本(即 24 比特和 48 比特)真彩色支持
  • 8 比特和 16 比特模式下的完全 alpha 透明度
  • “调色板 alpha”模式,有效地将普通 RGB 调色板转换为 RGBA
  • 伽马校正用于跨平台“亮度”控制



png 文件版本

[编辑 | 编辑源代码]

PNGN = PNG N 位每颜色(= 通道数 * 每通道位数)

  • PNG8 具有 2^8 = 256 种灰度或 256 种索引颜色,具有 8 位样本,通常意味着不透明或具有 GIF 式二进制透明度,但有时也包括半透明度[1]
  • PNG16
    • 灰色
      • 此类图像通常仅用于科学、医学和电影行业
      • 它将颜色空间均匀地分成 种灰度[2]
      • 请注意,当显示设备不支持 16 位时,它可能会被转换为 8 位以进行显示。任何大于 256 的值将简单地被裁剪为 255。[3]
  • PNG24 的颜色深度为 8 x 3 个通道(RGB),即每像素颜色为 24 位 = 种总颜色,2^8 = 256 种灰度 = 真彩色
  • PNG32 的颜色深度为 8 x 4 个通道(RGBA),即每像素颜色为 32 位 = 种颜色 = 真彩色和 alpha
  • PNG48
    • RGBA:颜色深度为 12 x 4 个通道(RGBA),即每像素颜色为 48 位 = 种颜色 = 真彩色和 alpha
    • RGB
  • PNG64 的颜色深度为 16 x 4 个通道(RGBA),即每像素颜色为 64 位 = 种颜色

关键词

[编辑 | 编辑源代码]
  • 样本 = 图像中通道和像素的交点。
  • 样本深度 = 用于表示样本值的位数。在索引颜色 PNG 图像中,样本存储在调色板中,因此样本深度始终为 8,这是调色板的定义。在其他类型的 PNG 图像中,它与位深度相同
  • 标记图像 是明确分配了颜色配置文件的图像,如图像格式定义的那样。这通常通过包含国际色彩联盟 (ICC) 配置文件 [ICC] 来完成。[4]

文件格式

[编辑 | 编辑源代码]
  • PNG 文件以 8 字节签名(文件头)开头
  • 在头之后,是一系列块


一个块由四部分组成

  • 长度(4 字节,[5] 大端),
  • 块类型/名称(4 字节[6]
  • 块数据(长度字节)
  • CRC(循环冗余校验/校验和;4 字节[5])。CRC 是一个网络字节序 CRC-32,它根据块类型和块数据计算得出,但不包括长度。
长度 块类型 块数据 CRC
4 字节 4 字节 长度 字节 4 字节


文件头

[编辑 | 编辑源代码]
PNG 图像 使用 十六进制编辑器 应用程序在 Ubuntu 中查看。

PNG 文件的前 8 个字节是 8-字节 签名[7](魔术签名),具有以下(十进制)值”

  DEC: 137 80 78 71 13 10 26 10
  HEX:  89 50 4E 47 0D 0A 1A 0A 
  ASC:  NA  P  N  G \r \n NA \n 
值(十六进制 用途
89 最高位设置为检测不支持 8 位数据 的传输系统,并降低文本文件被错误地解释为 PNG 或反之的可能性。
50 4E 47 ASCII 中,字母 PNG,允许人们在文本编辑器中查看时轻松识别格式。
0D 0A 一个 DOS 风格的 换行符 (CRLF) 用于检测数据的 DOS-Unix 换行符转换。
1A 在 DOS 环境下,使用 type 命令显示文件时,用于停止显示的字节——文件结束符 字符。
0A 用于检测 Unix-DOS 换行符转换的 Unix 风格换行符 (LF)。

关键块

[编辑 | 编辑源代码]
  • IHDR 必须是第一个块;它包含(按顺序)图像的
    • 宽度(4 字节)
    • 高度(4 字节)
    • 比特深度(1 字节)比特深度是一个单字节整数,表示每个样本或每个调色板索引的位数(不是每个像素)。有效值为 1、2、4、8 和 16,但并非所有值都允许用于所有颜色类型。请参阅下表[8]
    • 颜色类型(1 字节,值为 0、2、3、4 或 6)
    • 压缩方法(1 字节,值为 0)
    • 过滤方法(1 字节,值为 0)
    • 交错方法(1 字节,值为 0“无交错”或 1“Adam7 交错”)(总共 13 个数据字节)。[9]
  • PLTE 包含调色板:颜色列表。
  • IDAT 包含图像,它可能在多个 IDAT 块中分割。这种分割会稍微增加文件大小,但可以以流方式生成 PNG。IDAT 块包含实际的图像数据,即压缩算法的输出流。[10]
  • IEND 标记图像结束;IEND 块的数据字段有 0 字节/为空。[11]


PNG 颜色类型
颜色
类型
名称 二进制 掩码 十进制值 二进制值
  A C P
0 灰度 0 0 0 0 0 0002
2 真彩色 0 0 1 0 颜色 2 0102
3 索引 0 0 1 1 颜色,调色板 3 0112
4 灰度和 alpha 0 1 0 0 alpha 4 1002
6 真彩色和 alpha 0 1 1 0 alpha,颜色 6 1102



颜色类型和比特深度的允许组合[9]
颜色类型 通道 允许的每个通道的位数
1 2 4 8 16
索引 1 1 2 4 8
灰度 1 1 2 4 8 16
灰度和 alpha 2 16 32
真彩色 3 24 48
真彩色和 alpha 4 32 64

辅助块

[编辑 | 编辑源代码]
  • bKGD 给出默认背景颜色。它旨在在没有更好的选择时使用,例如在独立的图像查看器中(但不在 Web 浏览器中;有关更多详细信息,请参阅下文)。
  • cHRM 给出显示色度 坐标的原色白点
  • dSIG 用于存储数字签名。[12]
  • eXIf 存储Exif 元数据。[13]
  • gAMA 指定伽玛。gAMA 块仅包含 4 个字节,其值表示伽玛值乘以 100,000;例如,伽玛值 1/3.4 计算为 29411.7647059 ((1/3.4)*(100,000)) 并转换为整数(29412)以进行存储。[14]
  • hIST 可以存储直方图,或图像中每种颜色的总数。
  • iCCP 是一个 ICC 颜色配置文件[15]
  • iTXt 包含关键字和UTF-8 文本,以及可能压缩和翻译的编码,用语言标记 标记。可扩展元数据平台 (XMP) 使用此块,关键字为“XML:com.adobe.xmp”。
  • pHYs 保存预期的像素大小(或像素纵横比);pHYs 包含“每单位像素,X 轴”(4 字节)、“每单位像素,Y 轴”(4 字节)和“单位说明符”(1 字节),总共 9 个字节。[16]
  • sBIT(有效位)指示源数据的颜色精度;此块包含总共 1 到 5 个字节,具体取决于颜色类型。[17][18][19]
  • sPLT 建议在全范围颜色不可用时使用的调色板。
  • sRGB 表示使用标准sRGB 颜色空间;sRGB 块仅包含 1 个字节,用于“渲染意图”(为渲染意图定义了 4 个值——0、1、2 和 3)。[20]
  • sTER 用于立体 图像的立体图像指示器块。[21]
  • tEXt 可以存储可以在ISO/IEC 8859-1 中表示的文本,每个块一个键值 对。“键”的长度必须在 1 到 79 个字符之间。分隔符为空字符。“值”可以是任何长度,包括零到最大允许的块大小减去关键字和分隔符的长度。“键”和“值”都不能包含空字符。开头或结尾的空格也不允许。
  • tIME 存储图像最后修改的时间。
  • tRNS 包含透明度信息。对于索引图像,它存储一个或多个调色板条目的 alpha 通道值。对于真彩色和灰度图像,它存储一个要被视为完全透明的单个像素值。
  • zTXt 包含压缩文本(以及压缩方法标记),其限制与 tEXt 相同。


渲染意图值(值名称描述)

  • 0 = 感知 用于优先考虑对输出设备色域的良好适应,以牺牲颜色度量精度为代价的图像,例如照片。
  • 1 = 相对色度 用于要求颜色外观匹配(相对于输出设备白点)的图像,例如徽标。
  • 2 = 饱和度 用于优先考虑在牺牲色调和亮度的情况下保留饱和度的图像,例如图表和图形。
  • 3 = 绝对色度 用于要求保留绝对颜色度量的图像,例如为不同输出设备(校样)准备的图像预览。


非常简单的 PNG 文件的结构
89 50 4E 47 0D 0A 1A 0A
PNG 签名
IHDR
图像头
IDAT
图像数据
IEND
图像结束
表示一个红色像素的最小 PNG 文件的内容
十六进制 作为字符

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
00 00 00 01 00 00 00 01 08 02 00 00 00 90 77 53
DE 00 00 00 10 49 44 41 54 08 D7 63 F8 CF C0 00
00 03 01 01 00 18 DD 8D B0 00 00 00 00 49 45 4E
44 AE 42 60 82

.PNG........IHDR
..............wS
.....IDAT..c....
.............IEN
D.B`.

IHDR 块
块中的偏移量 十六进制值 十进制值 文本 意思
0 0x0D 13 IHDR 块有 13 个字节的内容
4 0x49484452 IHDR 标识一个头块
8 0x01 1 图像宽 1 像素
12 0x01 1 图像高 1 像素
16 0x08 8 每个像素(每个通道) 8 位
17 0x02 2 颜色类型 2(RGB/真彩色)
18 0x00 0 压缩方法 0(唯一接受的值)
19 0x00 0 过滤方法 0(唯一接受的值)
20 0x00 0 不交错
21 0x907753DE 块的类型和内容的 CRC(但不包括长度)
IDAT 块
块中的偏移量 十六进制值 意思
0 0x10 IDAT 块有 16 个字节的内容
4 0x49444154 标识一个数据块
8 0x08 使用 256 字节窗口的 DEFLATE 压缩方法[22]
9 0xD7 ZLIB FCHECK 值,未使用字典,最大压缩算法[22]
10 0x63F8CFC00000 使用静态哈夫曼代码的压缩 DEFLATE 块,解码为 0x00 0xFF 0x00 0x00[23]
16 0x03010100 ZLIB 校验值:未压缩数据的 Adler32 校验和[22]
20 0x18DD8DB0 块的类型和内容的 CRC(但不包括长度)

以类似于 十六进制编辑器 的方式显示,左侧显示以 十六进制格式 显示的字节值,右侧显示来自 w:ISO-8859-1 的等效字符,无法识别的字符和控制字符用句号代替。此外,PNG 签名和各个块用颜色标记。请注意,它们很容易识别,因为它们具有可读的类型名称(在本例中为 PNG、IHDR、IDAT 和 IEND)。


  PNG Signature(8 bytes): 89 50 4E 47 0D 0A 1A 0A
    =======Chunk start=======
    IHDR Chunk:
        IHDR chunk length(4 bytes): 00 00 00 0D
        IHDR chunk type(Identifies chunk type to be IHDR): 49 48 44 52
        Image width in pixels(variable 4): xx xx xx xx
        Image height in pixels(variable 4): xx xx xx xx
        Flags in the chunk(variable 5 bytes): xx xx xx xx xx
        CRC checksum(variable 4 bytes): xx xx xx xx 
    =======Chunk end=======
    
 

读取 png

[编辑 | 编辑源代码]

使用 od 程序读取 png

od -c test.png | head -4

示例输出

0000000 211   P   N   G  \r  \n 032  \n  \0  \0  \0 004   C   g   B   I
0000020   P  \0     002   + 325 263 177  \0  \0  \0  \r   I   H   D   R
0000040  \0  \0  \0   `  \0  \0  \0   `  \b 006  \0  \0  \0 342 230   w
0000060   8  \0  \0  \0       c   H   R   M  \0  \0   z   %  \0  \0 200

程序

  • pngcheck,由 Greg Roelofs 编写的命令行程序
pngcheck -c *.png
pngcheck -cvt *.png

八度音阶

[编辑 | 编辑源代码]

八度音阶 代码,用于创建数组(内存图像)并将其保存到文件中[24]

# octave m-file based on the m-file by Chris King
# http://www.dhushara.com/DarkHeart/Viewers/source/siegel.m
# an MyImage here is a matrix for 24 bit (3 byte) colors

# load packages
pkg load image; # imwrite
pkg load miscellaneous; # waitbar

# constan values 
nx = 480;
ny = 480;
MyImage = zeros(ny,nx,3); # 2D matrix filled with zeros
magc=0.65;
dSide=1/magc;
Zxmin = -dSide;
Zxmax = dSide;
Zymin = -dSide;
Zymax = dSide;

stepy = (Zymax - Zymin)/(ny - 1);
stepx = (Zxmax - Zxmin)/(nx - 1);

# computations 
waitbar(0,'Please wait...'); # info 
for iy = 1:ny
  Zy = Zymax - iy*stepy; # invert y axis
  for ix= 1:nx
    Zx = Zxmin + ix*stepx;
    if(Zy>0 && Zx>0)  # first quadrant should be in upper right position
    MyImage(iy,ix,2)=255-MyImage(iy,ix,2);
    endif;
  end # for ix
  waitbar(iy/ny);
end # for iy
# 
image(MyImage); # display image 
imwrite(MyImage,'s.png' ); # save image to the file

图像集合

[编辑 | 编辑源代码]


创建 png 文件

[编辑 | 编辑源代码]


检查 png 文件

[编辑 | 编辑源代码]
file p.png


ICC 嵌入配置文件

编辑 png 文件

[编辑 | 编辑源代码]
  • 十六进制编辑器
    • 由于压缩算法的存在,在十六进制编辑器中编辑像素数据几乎是不可能的[25]
    • 可以编辑标题,
  • 使用在线 crc 计算器计算 png 的校验和
  • 使用 TS/JS[26]
  • pngcheck


十六进制转储

hexdump --canonical p.png 


显示官方 libpng 规范[27]中描述的 PNG 标题的输出

  • 以 8 字节块处理 PNG 文件
  • PNG 规范以十进制形式记录,根据十六进制转储文档,它由 %d 表示
  • 在每个整数后面添加一个空格,使输出完美
hexdump -n8 -e'8/1 "%d ""\n"' p.png


ICC 配置文件任务[28]

  • 从文件中提取 ICC 配置文件
  • 要删除 ICC 配置文件
  • 要嵌入 ICC 配置文件


从文件中提取 ICC 配置文件

exiftool -icc_profile -b -w icc somefile.png

要删除 ICC 配置文件

pngcrush -rem iCCP foo.png result.png

另请参阅

[编辑 | 编辑源代码]

参考资料

[编辑 | 编辑源代码]
  1. stackoverflow 问题:png8 和 png24 之间的区别?
  2. 位深度,作者 Michael Reichmann,2011 年 12 月 2 日
  3. stackoverflow 问题:16 位灰度 png
  4. csswg:css-color-4 术语
  5. a b Laphroaig, Manul (31 October 2017). PoC or GTFO. ISBN 9781593278984. 每个块包含四个部分:长度、块类型、块数据和 32 位 CRC。长度是一个 32 位无符号整数,表示仅块数据字段的大小
  6. Laphroaig, Manul (31 October 2017). - PoC or GTFO. ISBN 9781593278984. 块类型是 32 位 FourCC 代码,例如 IHDR、IDAT 或 IEND。 {{cite book}}: Check |url= value (help)
  7. W3C 20035.2 PNG 签名.
  8. 便携式网络图形 (PNG) 规范(第三版)W3C 第一个公开工作草案 2022 年 10 月 25 日
  9. a b W3C 200311.2.2 IHDR 图像头
  10. W3C 200311.2.4 IDAT 图像数据.
  11. W3C 200311.2.5 IEND 图像尾部.
  12. Thomas Kopp (17 April 2008). "PNG 数字签名:扩展规范".
  13. "PNG 1.2 规范扩展,版本 1.5.0". ftp-osl.osuosl.org.
  14. W3C 2003, 11.3.3.2 gAMA 图像伽玛.
  15. w3.org png 规范 iCCP
  16. W3C 2003, 11.3.5.3 pHYs 物理像素尺寸.
  17. W3C 2003, 11.3.3.4 sBIT 有效位.
  18. "PNG(便携式网络图形)规范\版本 1.0". w3.org. 检索于 2022 年 5 月 30 日. 4.2.6. sBIT 有效位,总共 13 字节 - 颜色类型 2 和 3 总共 6 字节
  19. Roelofs 2003, 有效位 (sBIT).
  20. "PNG 规范:块规范".
  21. "2006 年 PNG 新闻". Libpng.org.
  22. a b c Deutsch,L. Peter;Gailly,Jean-Loup (1996 年 5 月). "rfc1950". datatracker.ietf.org. 检索于 2021-08-18.
  23. Deutsch,L. Peter (1996 年 5 月). "rfc1951". datatracker.ietf.org. 检索于 2021-08-18.
  24. Chris King 的 Matlab 中的 Sigel 盘
  25. 使用十六进制编辑器破解图像文件 psychocod3r 2019 年 4 月 15 日
  26. Mathilde E. 2020 年 9 月 8 日:理解和解码 PNG,在 TypeScript 中的示例
  27. Hexdump 如何工作。Hexdump 帮助你调查二进制文件的内容。了解 hexdump 的工作原理。作者:Seth Kenlon (Red Hat 团队) 2019 年 8 月 12 日
  28. PNG-ICC-测试
华夏公益教科书