PNG压缩原理:DEFLATE算法为什么无损?

结论先行:PNG之所以是无损压缩,因为它使用DEFLATE算法——LZ77字典压缩和Huffman编码两步都是完全可逆的数学操作,解压后数据与原始数据逐字节一致。PNG的压缩流程是:像素数据先经过过滤行预测消除相邻像素间的冗余,再用DEFLATE算法压缩。一张3000x2000的UI截图,PNG从原始17.2MB压到0.35MB,降幅97.9%,且每个像素值不变。下面从PNG文件结构和DEFLATE算法原理两个层面详解。

如果你对图片压缩的整体方法还不太熟悉,建议先阅读图片压缩指南:JPG/PNG/WebP格式对比

一、PNG文件结构:数据怎么组织

PNG文件由一系列数据块(chunk)组成,每个chunk包含类型、长度、数据和校验四部分。理解这些chunk的作用,就理解了PNG文件的内部结构。

数据块全称功能是否必需典型大小
签名PNG Signature8字节文件标识(89 50 4E 47 0D 0A 1A 0A)必需8字节
IHDRImage Header图像基本信息(宽高/色深/颜色类型)必需25字节
IDATImage Data压缩后的像素数据(DEFLATE编码)必需不定(主体)
IENDImage End文件结束标记必需12字节
PLTEPalette调色板(索引色模式)索引色必需≤768字节
tRNSTransparency透明度信息可选不定
tEXtText文本元数据(作者/描述等)可选不定
gAMAImage GammaGamma校正信息可选16字节

PNG文件最核心的chunk是IDAT,它存储的就是经过过滤行预测和DEFLATE压缩后的像素数据。一张3000x2000的24位RGB图像,原始像素数据约17.2MB(3000x2000x3字节),经过PNG压缩后IDAT部分可能只有0.3-0.5MB。压缩效果主要取决于图像内容的可重复性——大面积纯色压缩率最高,噪点照片压缩率最低。

二、DEFLATE算法原理:LZ77+Huffman两步压缩

PNG的核心压缩引擎是DEFLATE算法,它由两个步骤组成:第一步LZ77字典压缩消除重复序列,第二步Huffman编码消除编码冗余。两步都是无损可逆操作,这就是PNG压缩无损的根本原因。

步骤算法原理消除的冗余可逆性
第一步LZ77查找重复字节序列,用(距离,长度)引用替代重复序列冗余完全可逆
第二步Huffman编码高频数据用短码,低频数据用长码编码冗余完全可逆

1. LZ77字典压缩

LZ77是一种"滑动窗口"字典压缩算法。它维护一个滑动窗口(通常32KB),在窗口内查找与当前位置匹配的最长字节序列。如果找到匹配,就用一个(距离, 长度)引用替代这段字节;如果没有匹配,就输出原始字节。

举例说明:假设图像数据中有连续的白色像素(RGB 255,255,255),重复1000次。LZ77会在窗口中找到这个重复模式,第一个三元组记录后,后续999个三元组都替换为一个引用"回退3字节,复制3字节,重复999次"。3000字节的原始数据被压缩成十几个字节的引用序列,压缩率超过99%。

数据特征LZ77压缩效果典型压缩率原因
大面积纯色极好95%+重复序列长,引用替代效率高
水平渐变70%-85%渐变模式可匹配
规则纹理60%-80%纹理重复可引用
随机噪点0%-10%无重复序列可匹配
自然照片5%-20%像素差异大,匹配少

2. Huffman编码

LZ77输出的数据(引用和原始字节混合)再经过Huffman编码。Huffman编码的核心思想是:出现频率高的符号用短编码,频率低的用长编码,从而降低平均编码长度。

举例:如果LZ77输出中"引用标记"出现频率占60%,原始字节值255出现20%,其他值各占少量比例。Huffman会给"引用标记"分配2位编码,给255分配3位编码,给低频值分配8-12位编码。这样平均每个符号的编码长度从固定的8位降低到3-4位,进一步压缩约50%。

DEFLATE使用两种Huffman编码方式:固定Huffman树(预设编码表,速度快但压缩率一般)和动态Huffman树(根据实际数据频率构建最优编码表,压缩率更高但需额外存储编码表)。PNG标准要求使用动态Huffman编码以获得最佳压缩效果。

三、无损压缩机制:过滤行预测+DEFLATE

PNG的无损压缩不仅依赖DEFLATE算法,还有一个关键的预处理步骤——过滤行预测(Filter)。这一步在DEFLATE之前执行,目的是让像素数据更适合LZ77压缩。

图像中相邻像素通常有相似的值(比如蓝天区域像素值接近)。过滤行预测通过将每个像素值减去其左侧或上方像素值,将绝对值转换为差值——差值通常很小或为零,这种数据模式更适合LZ77和Huffman压缩。

过滤类型名称预测公式适用场景
0None不预测,原始值无规律的噪点数据
1Sub当前值 - 左侧值水平渐变图像
2Up当前值 - 上方值垂直渐变图像
3Average当前值 - (左+上)/2平滑过渡图像
4Paeth当前值 - Paeth预测值通用(大多数图像最优)

PNG编码器对每一行可以独立选择过滤类型。智压通 SmartSlim 基于自研 Rust 压缩引擎,会对每行尝试全部5种过滤方式,选择压缩效果最优的一种,这比固定使用单一过滤方式能额外减小10%–20%体积。

完整压缩流程:
原始像素 -> 过滤行预测(选最优过滤) -> LZ77字典压缩 -> Huffman编码 -> IDAT数据块

解压流程完全逆向:
IDAT数据块 -> Huffman解码 -> LZ77解压 -> 逆过滤还原 -> 原始像素

两步都是精确的数学逆运算,解压后的像素数据与原始数据逐字节相同,这就是PNG无损的根本保证。

四、实测:PNG vs JPEG vs WebP体积对比

我们用同一组测试图片对比三种格式的压缩效果,覆盖不同类型的图像内容。

图片类型尺寸原始BMPPNGJPEG(q80)WebP(q80)PNG压缩率
UI截图1920x10805.93MB0.35MB0.82MB0.28MB94.1%
线框图2000x15008.58MB0.42MB1.15MB0.35MB95.1%
自然照片3000x200017.16MB12.50MB1.80MB1.42MB27.2%
人像照片4000x300034.33MB28.80MB3.50MB2.80MB16.1%
图标集1024x10243.00MB0.08MB0.45MB0.06MB97.3%
扫描文档2480x350824.80MB1.20MB0.85MB0.72MB95.2%

实测数据揭示了一个关键结论:PNG的压缩效果高度依赖图像类型。对于UI截图、线框图、图标等含大量纯色区域的图像,PNG压缩率高达94%–97%,远超JPEG。但对于自然照片、人像照片等像素差异大的图像,PNG压缩率仅16%–27%,远不如JPEG的89%–90%。

再看PNG优化前后对比,以标准PNG和优化PNG为例:

图片类型标准PNG优化PNG优化后降幅优化方式
UI截图0.42MB0.35MB16.7%Paeth过滤+zlib最高级
线框图0.52MB0.42MB19.2%逐行最优过滤+删元数据
图标集0.12MB0.08MB33.3%转8位索引色+优化过滤
扫描文档1.50MB1.20MB20.0%逐行最优过滤+删gAMA

智压通 SmartSlim 的PNG优化能比标准PNG再减小15%–33%体积,核心就是逐行最优过滤选择和zlib最高压缩级别的组合使用。

更多格式对比,可以参考无损压缩vs有损压缩:核心区别WebP vs PNG vs JPG格式对比

五、常见问题FAQ

Q1:PNG为什么是无损压缩?

PNG使用DEFLATE算法压缩数据,该算法由LZ77字典压缩和Huffman编码两步组成。LZ77通过查找重复字节序列并用距离+长度引用替代,Huffman用变长编码让高频数据用短码。两步都是可逆操作——解压时Huffman解码还原变长码,LZ77根据引用恢复原始字节,数据完全一致不丢失任何信息,因此PNG是无损压缩。

Q2:PNG和JPEG哪个压缩率更高?

照片类图片JPEG压缩率远高于PNG。一张3000x2000照片,PNG约12.5MB,JPEG质量80约1.8MB,相差7倍。因为JPEG采用有损DCT变换丢弃高频细节,而PNG必须无损保留每个像素。但对于线框图、截图、图标等含大面积纯色的图片,PNG反而更小——一张UI截图PNG 0.3MB,JPEG质量80约0.8MB。选格式要看内容类型。

Q3:PNG压缩率最高能到多少?

取决于图片内容。大面积纯色或渐变的图片压缩率可达90%以上(如UI截图从5MB压到0.3MB);噪点多的照片压缩率通常只有10%-30%,因为像素差异大、LZ77找不到重复序列。PNG使用DEFLATE算法的理论极限约在ZIP压缩水平,无法像JPEG那样通过丢弃信息获得极高压缩率。

Q4:PNG优化和PNG压缩有什么区别?

PNG压缩指将原始像素数据用DEFLATE编码为PNG格式,是标准流程。PNG优化是在标准压缩基础上进一步减小体积,包括:尝试5种过滤行预测选最优、使用zlib最高压缩级别、删除元数据chunk(如tEXt/gAMA)、将24位RGBA转为8位索引色(如果颜色≤256种)。智压通 SmartSlim 的PNG优化能比标准PNG再减小15%-30%体积。

总结

PNG之所以能做到无损压缩,核心在于DEFLATE算法的LZ77和Huffman两步都是完全可逆的数学操作,加上过滤行预测预处理提升数据可压缩性。PNG对UI截图、线框图、图标等大面积纯色图像压缩效果极佳(压缩率94%–97%),但对照片类图像压缩率有限(16%–27%),这种场景应选JPEG或WebP。

如果你需要优化PNG图片体积,智压通 SmartSlim 基于 Rust 压缩引擎提供逐行最优过滤和zlib最高级别压缩,比标准PNG再减小15%–33%体积,支持 png/jpg/jpeg/webp/bmp/tiff 等 9 种图片格式,本地压缩数据不出域。

需要压缩文件?试试智压通 SmartSlim

基于自研 Rust 压缩引擎,支持 PDF/图片/视频/Office/OFD 等 10 大类 40+ 格式,本地压缩数据不出域。