同一张照片缩到 64 像素,有的工具出来很清楚,有的一团糊,还有的凭空多出细密的花纹。
这三种结果对应着重采样过程里的三个不同问题,而它们的解法完全不同。
先分清方向:缩小和放大不是同一件事
| 缩小 | 放大 | |
|---|---|---|
| 信息量 | 在减少 | 不增加 |
| 能不能做好 | 能,取决于算法 | 只能让糊得好看一点 |
| 主要风险 | 混叠、发灰 | 模糊、块状、锯齿 |
这个区分是后面所有讨论的前提:缩小是个可以做好的工程问题,放大不是。
四种插值算法
| 算法 | 参考邻域 | 特点 | 适合 |
|---|---|---|---|
| 最近邻 | 1 个像素 | 硬边完全保留,放大出方块 | 像素画、二值图 |
| 双线性 | 2×2 | 快,偏软 | 实时预览 |
| 双三次 | 4×4 | 比双线性锐,可能轻微过冲 | 通用,最常见 |
| Lanczos | 更大的窗 | 缩小质量最好,边缘可能有振铃 | 高质量缩图 |
唯一需要记死的一条:像素画和二值图必须用最近邻。任何插值都会在硬边上算出中间色,把「一个像素就是一个像素」的美学彻底破坏掉。
缩小的真正难点:混叠
把一张 2000 像素宽的图一步缩到 64,相当于每 31 个像素只取 1 个。
原图里比这个采样间隔更细的花纹会怎么样?
- 衬衫的细格子
- 建筑远景的百叶窗
- 含小号文字的屏幕截图
它们会被采出完全错误的低频图案——看起来像水波纹,这就是摩尔纹,本质是混叠(aliasing)。
正确做法是先把高频去掉,再抽样:先做一次低通(模糊),把细到采不出来的成分抹掉,然后再降采样。
逐级折半:低通的廉价近似
不想实现完整的低通滤波器,有一个简单有效的替代:
2000 → 1000 → 500 → 250 → 125 → 64
每次只缩一半。缩一半时用 2×2 邻域取平均,天然就是一次低通。走完几级再落到目标尺寸,花纹就不会冒出来。
这也是 图片尺寸修改 内部的做法——浏览器 drawImage 的默认插值只看相邻几个像素,一步缩十倍会直接跳过大量信息,逐级折半比一次性缩过去清楚得多。
缩完发灰,是正常的
降采样本质上是一次平均,相邻像素的差异被抹平,边缘对比度必然下降。
补救办法是缩完之后做一次轻微锐化(USM,半径小、量适中),把边缘的局部对比度拉回来。
两个注意点:
- 顺序是先缩后锐。反过来会把噪点一起放大再采进去
- 不要靠加大锐化量硬凑。过度锐化会在边缘产生白边和黑边,尺寸越小越明显
目标尺寸特别小的时候,比起反复调锐化,换一张线条更粗、细节更少的源图收益大得多。
放大:插值在算,AI 在编
传统插值不增加任何信息。 双三次、Lanczos 做的都是「根据已有像素算出中间值」,所以放大后只有两种结局:模糊,或者块状加锯齿。
AI 超分是另一回事:模型根据训练时见过的大量图像,猜这里本来应该长什么样。
这个区别在实用上很关键:
- 照片放大做壁纸、海报 → AI 超分通常效果不错
- 证件、票据、监控截图、有文字的图 → 不要用 AI 超分。猜出来的笔画可能把字改了,而且从结果上看不出来
- 像素画 → 必须最近邻
最好的办法永远是回去找原图。 图片尺寸修改 允许填比原图大的数字,但不做任何插值猜测——它不会假装能恢复细节。
图标:小尺寸要重画,不是缩
一套 App 图标从 1024 缩出全部尺寸,大的没问题,小的会出事:
| 目标尺寸 | 做法 |
|---|---|
| 512 以上 | 从矢量或 1024 源图直接导出 |
| 64 – 256 | 从源图缩,缩完检查边缘,必要时轻微锐化 |
| 16 – 48 | 建议重新设计 |
小尺寸下一个像素的权重极大,缩出来常见三种毛病:笔画粗细不匀、边缘出现半透明的灰边、图形中心偏移一个像素。
真正的解法是从矢量出图——SVG 在每个尺寸各导出一次,让渲染器在每个尺寸上各自对齐像素网格。
还有一条不管什么尺寸都成立:每个尺寸都从同一张源图导出。不要用「先缩到 256、再从 256 缩到 128」这种链式做法,有损格式会把压缩痕迹一层层累积下去。
顺带:几个相邻的问题
- 要的是「压到多少 KB」而不是「改成多少像素」 → 那是压缩工具的活,见 图片压缩的几种策略
- 格式选 PNG 还是 WebP、JPEG 有什么代价 → JPG / PNG / WebP / AVIF 怎么选
- 转换格式时的常见坑(透明丢失、色彩偏移) → 图片格式转换的坑
- 社交平台的封面尺寸规则 → OG 图 1200×630 与各平台规则
一句话
缩小做得好不好,全看有没有先低通再抽样;放大做得再好,也只是把猜的东西画得更像。