缩放图片是图片处理中最常见的操作,但很多人直接用 resize() 默认参数,结果图片模糊、锯齿严重。本文讲清楚 PIL 缩放时如何保证高质量输出。
一、先看效果对比
同一张图缩小到 800×600,不同参数的效果:
| 方式 | 效果 |
|---|---|
| 默认(BILINEAR) | 边缘模糊,细节丢失 |
| BICUBIC | 稍好,但仍有锯齿 |
| LANCZOS | 清晰锐利,细节保留最好 |
| NEAREST | 像素块状,仅适合像素画 |
二、核心:指定 resample 参数
PIL 的 resize() 默认用 BILINEAR,质量一般。高质量缩放只需加一个参数:
python
from PIL import Image
img = Image.open("大图.jpg")
# ❌ 默认(质量一般)
small = img.resize((800, 600))
# ✅ 高质量(推荐)
small = img.resize((800, 600), resample=Image.LANCZOS)
一句话:加上 resample=Image.LANCZOS,就够了。
三、所有滤波器对比
| 滤波器 | 写法 | 质量 | 速度 | 适用场景 |
|---|---|---|---|---|
| NEAREST | Image.NEAREST |
⭐ | 最快 | 像素画、标签图 |
| BILINEAR | Image.BILINEAR |
⭐⭐ | 快 | 实时预览(默认) |
| BICUBIC | Image.BICUBIC |
⭐⭐⭐ | 中等 | 一般用途 |
| LANCZOS | Image.LANCZOS |
⭐⭐⭐⭐⭐ | 较慢 | 最终输出 |
结论:只要不是追求速度,无脑选 LANCZOS。
四、PIL 版本差异
PIL 10.0+(2024年后)写法有变化:
python
# 旧版本(< 10.0)
img.resize((800, 600), resample=Image.LANCZOS)
# 新版本(>= 10.0)
img.resize((800, 600), resample=Image.Resampling.LANCZOS)
两种都能用,新版本更规范。
五、保存时也要注意质量
缩放完保存 JPEG 时,默认 quality=75,会再次压缩导致模糊。保存时也要指定质量:
python
small.save("out.jpg", quality=95, subsampling=0)
| 参数 | 作用 | 推荐值 |
|---|---|---|
quality |
JPEG 压缩质量 | 90~95 |
subsampling |
色度采样,0=不采样 | 0(最高质量) |
optimize |
优化文件大小 | True |
六、完整高质量流程
python
from PIL import Image
img = Image.open("大图.jpg")
# 1. 缩放(LANCZOS 保证缩放质量)
small = img.resize((800, 600), resample=Image.LANCZOS)
# 2. 保存(quality=95 保证保存质量)
small.save("小图.jpg", quality=95, subsampling=0, optimize=True)
三步:LANCZOS 缩 → quality=95 存 → subsampling=0 禁色度采样。
七、放大图片也用 LANCZOS
很多人以为放大该用 NEAREST 保持像素感,错。LANCZOS 放大同样最优:
python
# 放大 2 倍,依然用 LANCZOS
big = img.resize((4000, 3000), resample=Image.LANCZOS)
NEAREST 放大只会出现马赛克,LANCZOS 放大细节更自然。
八、常见坑
| 坑 | 原因 | 解决 |
|---|---|---|
| 缩放后模糊 | 没加 resample,默认 BILINEAR | resample=Image.LANCZOS |
| 保存后更模糊 | JPEG quality 默认 75 | quality=95 |
| 颜色发灰 | 色度采样 subsampling=1 | subsampling=0 |
| PIL 10+ 报错 | 旧写法不兼容 | 用 Image.Resampling.LANCZOS |
| 透明图缩放后变黑 | RGBA 转 RGB 丢失透明 | 用 Image.new("RGBA", ...) 保持模式 |
九、总结
| 操作 | 关键参数 |
|---|---|
| 缩放 | resample=Image.LANCZOS |
| 保存 JPEG | quality=95, subsampling=0 |
| 保存 PNG | 直接存,PNG 无损 |
| 放大 | 同样用 LANCZOS,别用 NEAREST |
记住一句话:resize 加 LANCZOS,save 加 quality=95,图片质量就有保障了。