你有没有好奇过一件事 手机拍一张照片动不动就是好几兆 可发到微信里 几秒钟就传完了 画质看起来也没差多少 这中间发生了什么 答案是压缩 而且是一种很狡猾的压缩
先说说数字图像的本质 一张照片在电脑眼里就是一个巨大的数字表格 横竖排满一个个小格子 每个格子叫像素 每个像素用三个数字记录颜色 红绿蓝 各占一个字节 一张1200万像素的照片 光存这些数字就要 1200万乘3 也就是3600万字节 约34兆 这还只是一张 所以如果原样保存 手机内存早就爆了
那压缩靠什么呢 靠两件事 找冗余 和 骗眼睛
冗余是数据里重复的部分 天空一大片都是同一个蓝色 没必要每个像素都存一遍 这是空间冗余 相邻像素颜色相近 差不了多少 这是更普遍的情况 聪明的算法不存每个像素的绝对值 而是存相邻像素之间的差值 差值往往很小 需要的位数就少 这叫差分编码 无损压缩的PNG格式主要就靠这类手段 压缩完还能100%还原 一点不丢
但JPEG更狠 它走的是有损路线 主动扔掉一些信息 关键是扔得让你看不出来 这就用到人眼的弱点 人类视觉对亮度极其敏感 但对颜色的分辨能力差得多 于是JPEG先把每个像素的RGB转成亮度和两个颜色分量 然后把颜色分量的分辨率砍掉一半甚至四分之三 这叫色度抽样 你看天空还是那片天空 但颜色数据已经少了一大截
接下来是JPEG最核心的魔术 离散余弦变换 简称DCT 它把8乘8的小块像素 从 每个点的亮度 改写成一堆频率系数 第一项代表整块的总体亮度 后面的项代表细节变化 快的变化 也就是高频 对应锐利的边缘 慢的变化 低频 对应平滑的区域 人眼对高频细节其实不太敏感 于是JPEG把高频系数大幅缩小 很多直接归零 这叫量化 这一刀砍下去 数据量骤降 但画面只是稍微糊了一点 不放大根本看不出
最后再用哈夫曼编码把剩下的一串数字变短 出现频率高的用短码 低的用长码 就像把常用字 的了 设计成很短的笔画 最终 一张34兆的照片 常常能被压到两三兆 压缩率超过90%
所以同一个 质量 的照片 文件大小能差几十倍 全靠压缩率 而压缩率越高 扔掉的细节越多 这就是为什么有时候图片放大看会有方块状的马赛克 那些格子就是被量化砍掉细节的8乘8小块 压缩到极致时 JPEG还会出现一种叫振铃效应的模糊光晕 像照片边缘长了毛边
有趣的是 现在的手机相册 视频 网课画面 几乎全在玩同一套把戏 视频压缩更夸张 它还利用时间冗余 这一帧和上一帧只有少数像素在动 那就只记录动了的部分 于是 你看视频时那个流畅的世界 其实每一帧都充满了精心计算的 谎言
说到底 压缩是工程学里的一场交易 用一点点几乎察觉不到的质量损失 换取巨大的存储和带宽节约 它教会我们一件事 有时候 把东西变小的关键 不是删掉真正重要的部分 而是删掉那些 你根本注意不到的部分 这大概也是一种智慧