我的知识记录

Python 批量修改图片尺寸:等比缩放不拉伸教程

用 Python Pillow 批量把图片缩放到指定宽度或高度,保持宽高比不变形,支持最长边限制、LANCZOS 高质量缩放,附完整代码和注意事项。

场景痛点

做电商详情页要把所有主图统一成 800x800,做公众号封面要统一成 900x383,做简历证件照要统一成一寸。用画图工具一张张改,手动拉容易拉伸变形,几十张图半小时就没了。用 Python 脚本按等比缩放跑一遍,要么指定目标宽度、要么限制最长边,保证不变形,清晰度用 LANCZOS 重采样。

用到的库

pip install Pillow

完整代码

import os
from PIL import Image

SRC_EXTS = (".jpg", ".jpeg", ".png", ".webp")


def resize_by_width(img, target_width):
"""按目标宽度等比缩放,高度自动算"""
ratio = target_width / img.width
target_height = int(img.height * ratio)
return img.resize((target_width, target_height), Image.LANCZOS)


def resize_by_max_side(img, max_side=1920):
"""限制最长边不超过 max_side,原图比这小就不放大"""
w, h = img.size
longest = max(w, h)
if longest <= max_side:
return img.copy()
ratio = max_side / longest
new_size = (int(w * ratio), int(h * ratio))
return img.resize(new_size, Image.LANCZOS)


def batch_resize(src_dir, dst_dir, mode="width", target_width=800, max_side=1920):
"""批量缩放图片,mode=width 按宽度,mode=max 按最长边"""
os.makedirs(dst_dir, exist_ok=True)
for root, _, files in os.walk(src_dir):
for name in files:
if not name.lower().endswith(SRC_EXTS):
continue
src_path = os.path.join(root, name)
rel = os.path.relpath(src_path, src_dir)
dst_path = os.path.join(dst_dir, rel)
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
try:
with Image.open(src_path) as img:
if mode == "width":
out = resize_by_width(img, target_width)
else:
out = resize_by_max_side(img, max_side)
out.save(dst_path, "JPEG", quality=90, optimize=True)
print(f"已缩放:{src_path} -> {out.size}")
except Exception as e:
print(f"失败:{src_path},原因:{e}")


def main():
# 把所有图宽度统一缩到 800
batch_resize("./photos", "./photos_800w", mode="width", target_width=800)
# 或者把所有图最长边压到 1920,适合上传网站
# batch_resize("./photos", "./photos_1920", mode="max", max_side=1920)


if __name__ == "__main__":
main()

代码讲解

  • 等比缩放的关键是先算比例 ratio = 目标宽度 / 原宽度,再用同一个比例乘高度,宽高比不变就不会变形。
  • Image.LANCZOS 是 Pillow 里最高质量的重采样滤波器,缩小图片时边缘最干净,比默认的 BICUBIC 还清晰一点。
  • resize_by_max_side 适合"大图压小、小图不动"的场景,先判断原图最长边是不是已经小于限制,小于就直接拷贝返回,不做无意义放大(放大只会糊)。
  • img.copy() 防止后面 save 时改到原图对象。
  • 输出统一存成 JPEG quality=90,网页用足够清晰,体积也小。

运行结果

运行后在 ./photos_800w 下生成宽度为 800 的等比缩放图,每张图高度按原始比例计算,控制台打印目标尺寸。手机竖拍的图会变成 800x1200 这种,横拍的变成 800x533,不会拉伸。

注意事项

  • 不要为了填满目标尺寸强行 resize((800,800)),除非你真的想要拉伸变形;要正方形就先等比缩放再补白边。
  • 放大图片(小图变大图)一定会模糊,脚本里 max_side 模式特意不做放大,width 模式需要自己判断。
  • 横图竖图混在一起时,按宽度缩放会让竖图变得很矮,这种场景用 max_side 模式更稳。
  • 输出目录和原图分开,脚本只读原目录。

Python 批量修改图片尺寸:等比缩放不拉伸教程

标签:

更新时间:2026-09-14 20:43:19

上一篇:Python 密码强度检测:正则+评分给密码打分教程

下一篇:Python 批量提取图片 EXIF 信息:拍摄时间相机型号 GPS 教程