图形学 | 格物致知!PNG 除了无损压缩你还知道什么?

前言

  • PNG(Protable Network Graphics,便携式网络图形) 是一种非常常见的图片格式,深入理解 PNG 文件原理,有利于加强对图片编解码过程的理解,便于开展优化工作。
  • 在这篇文章里,我将带你探究 PNG 图片的 数据结构 & 编码原理 & 优化方法等。如果能帮上忙,请务必点赞加关注,这真的对我非常重要。

系列文章


目录


1. 概述

1.1 定义

PNG(Portable Network Graphics,便携式网络图形)是一种 无损压缩的位图图形格式。它本身的设计目的是替代 GIF 格式,所以它与 GIF 有一些相似之处。

1.1 特点

  • 无损压缩(Lossless Compression):采用了 LZ77 派生算法 + Huffman 编码,压缩率更高,体积更小且不损失数据;

  • 支持透明:支持 8 位透明通道,而 GIF 只支持 1 比特透明通道,JPEG 不支持透明通道;

  • 图像的复杂程度越低,使用 PNG 格式的压缩率更高(原因见 第 3 节 编码原理);

  • 支持五种像素 / 颜色类型

    • 索引色(Indexed-colour,8 位)
    • 灰度(Greyscale,8 位)
    • 真彩色(Truecolour,24 位)
    • 灰度透明(Greyscale with alpha,16 位)
    • 真彩色透明(Truecolour with alpha,32 位)
引用自 https://www.w3.org/TR/2003/REC-PNG-20031110/ —— w3.org

提示: 网上所述三种 PNG 类型为:PNG 8、PNG 24、PNG 32,经查阅百科、PNG 官网和《PNG 文件协议》未能找到支撑依据,本文不作阐述。


2. PNG 数据结构

这一节我们来讨论 PNG 图片的数据结构,一个 PNG 格式文件(或数据流)由一个 8 字节的签名和若干个数据块(chunk)组成。

2.1 PNG 签名

PNG 文件头部的 8 字节为文件签名(或称魔数),这个值将被用来识别文件是否为 PNG 文件,数据固定为8950 4E47 0D0A 1A0A。以下是我任意打开的一个 PNG 文件:

提示: 使用 010 Editor 可以查看文件二进制数据。首次打开 PNG 文件时,它会提示安装 PNG.bt,安装后将帮助解析你读懂每块数据的含义。

2.2 数据块

  • 数据块类型

PNG 定义了两种数据块:关键数据块(critical chunks)& 辅助数据块(ancillary chunks)

其中,关键数据块是从 PNG 数据流中成功解码图像所必需的,而辅助数据块是可选的,我们将重点了解关键数据块。关键数据块分为四种:文件头数据块、调色板数据块、图像数据块和图像结束数据块。

  • 数据块的内部结构

PNG 的每一块数据块都由四个部分组成:

名称 字节数 描述
长度(length) 4 指定数据块中数据域的长度
数据块类型码(Chunk Type Code) 4 由(A-Z、a-z)组成
数据 length 数据块数据
循环冗余检测(CRC) 4 用于检错
  • 文件头数据块 IDHR(header chunk)

文件头数据块是 PNG 文件中的第一个数据块,包含了 PNG 文件的基本信息,由 13 个字节组成,数据结构如下:

字段 字节数 描述
图片宽度(Width) 4 以像素为单位
图片高度(Height) 4 以像素为单位
图像深度(Bit depth) 1 /
颜色类型(ColorType) 1 5 种颜色类型:
索引色
灰度
灰度透明
真彩色(24 位直接色)
真彩色透明(32 位直接色)
压缩方法(Compression method) 1 LZ77 派生算法
滤波方法(Filter method) 1 /
隔行扫描方法(Interface method) 1 0:非隔行扫描
1: Adam7(7遍隔行扫描方法)
  • 调色板数据块 PLTE(palette chunk)

调色板数据块包含有与索引彩色图像(indexed-color image)相关的彩色变换数据,它仅与索引彩色图像有关,而且要放在图像数据块 IDAT 之前。真彩色的 PNG 数据流也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。

  • 图像数据块 IDAT(image data chunk)

图像数据块是图像实际存储的数据,可包含多个连续顺序的图像数据块。

  • 图像结束数据块 IEND(image trailer chunk)

图像结束数据块标记 PNG 文件或者数据流已经结束,必须要放在尾部。


3. PNG 编码原理

通过查阅《Protable Network Graphic (PNG) Specification (Second Edition)》,可以了解到 PNG 文件的编码过程主要分为五个阶段:

  • 1、通过提取(pass extraction)
  • 2、扫描线序列化(scanline serialization)
  • 3、过滤(filtering)
  • 4、压缩(compression)
  • 5、分块(chunking)

前两个步骤我看不懂,我直接讲后三个步骤。

3.3 滤波(filtering)

这个步骤的主要思想是 增量编码,即:一个值可以表示为与前值的差值。

例如:[2,3,4,5,6,7,8]可以编码为[2,3-2=1,4-3=1,5-4=1,6-5=1,7-6=1,8-7=1] =>[2,1,1,1,1,1,1]

可以发现,增量编码后的数据变成了大量重复、低值的数据,这样的数据是有利于压缩的,原因我在 第 3.4 节 说。

回到 PNG 的滤波步骤,这个步骤主要是选择合适的差分过滤器,分别处理每一行中的每个像素,使得差分编码的数值尽可能重复、尽可能小,要点如下:

  • 1、滤波器有以下五种
引用自 https://zh.wikipedia.org/wiki/PNG —— 维基百科

在后面的 分块(chunking) 步骤中,会把编码过程中使用的滤波方法被记录 IHDR 中的Filter method字段里。

  • 2、为了最优效果,每一行可使用不同滤波器
引用自 https://medium.com/@duhroach/how-png-works-f1174e3cc7b7 —— Colt McAnlis 著
  • 3、滤波却是按通道而不是按像素进行的

滤波是按通道而不是按像素进行的,也就是说滤波是先扫描一行中像素的红色通道,然后再扫描一行中像素的蓝色通道,以此类推。

  • 4、一行中所有通道使用相同的滤波器

3.4 压缩(compression)

PNG 的压缩过程结合了 LZ77 编码和 Huffman 编码,要点如下:

  • 1、压缩过程是无损压缩
  • 2、颜色越单一,颜色差异越小,压缩率越大

LZ77 编码

一种基于字典的、“滑动窗”的无损压缩算法。

Huffman 编码(霍夫曼编码)

一种用于无损压缩的变长编码,主要思想为:评估码元的出现几率选择不同长度的编码,几率较高的码元使用较长的编码,而几率较低的码元使用较长的编码,这将使得编码的平均长度降低。

3.5 分块(chunking)

分块可方便地将压缩数据流分解为可管理的块,关于数据块的结构我们在 第 2 节中讨论过。


4. 缩小 PNG 文件大小

4.1 减少颜色数量 & 差异

第 3 节 编码原理 的讨论,我们提到了 增量编码 的概念,通过减少颜色的数量 & 差异,滤波步骤之后数据的差异更小,有利于在压缩步骤中缩小文件。

不过,减少颜色的数量 & 差异等同于给图片进行了有损编码,应当确保在高效压缩和图片质量之间保持适当的平衡。

4.2 采用索引色格式

如果图片的单色数量不超过 256 个,则可以采用Indexed-colour(索引色)格式。原始图像的每个像素由调色板中的一个索引表示。此时,每个像素的字节数由 3 字节(无透明通道)和 4 字节(有透明通道)减少到 1 字节,大大缩小文件。

引用自 https://developer.android.com/topic/performance/network-xfer —— Android Developers

4.3 采用矢量量化(vector quantization)

如果图片的单色数量超过 256 个,就需要 采用矢量量化较少颜色数量,再生成索引色格式。矢量量化就是将颜色相似的一块区域合并为同一种颜色的舍入的过程,主要分为以下步骤:

  • 1、根据相近区域相似度进行分组;
  • 2、将该组中所有颜色替换为单个中心点的颜色;
  • 3、生成索引色格式。
引用自 https://developer.android.com/topic/performance/network-xfer —— Android Developers

5. PNG 的有损压缩方案

第 3 节 编码原理 中我们提到了 PNG 压缩是无损压缩,为了进一步提高压缩率,可以采用有损压缩算法,以下是现有的 PNG 有损压缩方案。

在官网介绍中,其实可以清楚地了解到它们的原理,主要就是采用了 第 4.3 节 讨论的方案:采用矢量量化较少颜色数量,再生成索引色格式。

5.1 TinyPNG

官方地址:tinypng.com

How does it work?

...... This technique is called “quantization”. By reducing the number of colors, 24-bit PNG files can be converted to much smaller 8-bit indexed color images. All unnecessary metadata is stripped too. The result better PNG files with 100% support for transparency. Have your cake and eat it too!

局限:只提供了 HTTP 请求的方式,并且有次数限制。

5.2 pngquant

官方地址:pngquant.org

Features

High-quality palette generation using a combination of vector quantization algorithms.
......

5.3 zopflipng

5.4 pngcursh

Editting...


参考资料

推荐阅读

感谢喜欢!你的点赞是对我最大的鼓励!欢迎关注彭旭锐的GitHub!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容