📄 一句话概括
无损压缩只改【怎么表示】,不改【表示什么】——所以天花板只有 2 倍上下,它靠的是统计冗余。
📝 本节和前面几节的关系
6.1 立了总纲,6.2 开始分类。第一刀是分【无损】与【有损】,这一节先讲无损。
一、无损压缩做什么
无损压缩的定义只有一句:压缩前和解压后的数据完全一样。 所以它不能丢任何信息,只能在【表示方式】上做文章。 它能利用的只有一类冗余:统计冗余——数据里出现的重复与规律。
二、三类常见做法
游程编码(RLE):连续重复的值记成【值 + 次数】。 适合大片相同的数据,比如画面里大块的纯色区域。 霍夫曼编码:出现得多的符号给短码,出现得少的给长码。 算术编码:把整串符号映射成一个小数,效率比霍夫曼略高。 三种思路不同,但目标一致:用更少的比特表示同样的信息。
三、为什么只有 2 倍上下
因为这个上限是信息论决定的,不是实现水平问题。 数据的【信息量】本身是固定的,你只能去掉表示上的浪费,不能减少信息本身。 所以 FLAC 约 2 倍、PNG 约 2~3 倍——它们都顶着同一堵墙。 反过来说:看到某个【无损压缩】宣称压了 10 倍,那一定是搞错了什么。
四、它在哪里不可替代
两类场景必须用无损: 要反复编辑的中间素材——每存一次就损一次,绝对不行; 有标准化要求的交付——比如医学影像、母版存档。 所以无损不是【低效】,它是为了保住【可反复处理】这个前提。
五、动手 Demo:无损压缩的三类做法
无损压缩不丢信息,所以只能从【表示方式】上想办法。
rows = [("游程编码 RLE", "连续重复的值记成值+次数", "1.5~3 倍"),
("霍夫曼编码", "高频符号给短码", "1.5~2 倍"),
("算术编码", "把整串符号映射成一个小数", "比霍夫曼略高")]
for a, b, c in rows:
print("%-14s %-24s %s" % (a, b, c))
实跑输出:
--------------------------------------------------------------------
无损压缩的三类做法
--------------------------------------------------------------------
无损压缩不丢信息,所以只能从【表示方式】上想办法。
方法 原理 典型压缩比
--------------------------------------------------------------
游程编码 RLE 连续重复的值记成【值+次数】 1.5~3 倍
霍夫曼编码 高频符号给短码 1.5~2 倍
算术编码 把整串符号映射成一个小数 比霍夫曼略高
三种的共同点:**它们都只改变【怎么表示】,不改变【表示什么】。**
所以无损压缩的天花板不高——一般也就 2 倍上下。
三种的共同点:它们都只改变【怎么表示】,不改变【表示什么】。 所以无损压缩的天花板不高——一般也就 2 倍上下。
30 秒实验
- 用一个无损压缩工具压一段 WAV,记下压缩比。
- 再想一下:这个数字为什么顶在 2 倍左右。
常见误区
- 以为无损压缩能压很多。2 倍左右就是它的物理上限。
- 把无损压缩用于素材多次编辑。方向反了——它正是为这个场景存在的。
自测三问(点开对答案)
1. 无损压缩利用的是哪一类冗余? —— 统计冗余。 2. 三类常见的无损压缩做法是什么? —— 游程编码、霍夫曼编码、算术编码。 3. 为什么无损压缩只有 2 倍上下? —— 它不能减少信息量,只能去掉表示上的浪费,上限由信息论决定。- ☐ 下一节(6.2.2 有损压缩)
相关笔记
- 有损压缩 — 另一条路:允许丢
- 熵编码 — 霍夫曼在这里被用上
- 音频格式 — FLAC 的位置
- 🎬 FFmpeg入门详解 · 索引