用 Python 批量生成商品缩略图:Pillow 等比缩放与命名规范实战

举报
yd_295675147 发表于 2026/11/11 16:38:10 2026/11/11
【摘要】 电商运营每天要把相机原图批量做成统一尺寸的商品缩略图。本文给出可直接运行的 Python + Pillow 脚本:等比缩放、白底居中、统一命名,一次生成 800、1200、600 三档图片,并总结五个常见坑与验收清单。

做电商运营,每天要处理最多的图片就是商品图:一张 4000×3000 的相机原图,要变成店铺列表里的 800×800 方图、详情页里的 1200 宽长图、手机端瀑布流里的 600×600 小图。如果靠手工一张张在修图软件里改尺寸、改名字,一天下来既慢又容易出错。本文用 Python + Pillow 写一套可直接跑的批量脚本,把“等比缩放、居中留白、统一命名、跳过已处理文件”一次做到位。

一、先定规则:尺寸与命名比代码更重要

很多缩略图问题的根源不在代码,而在没有规则。建议一个店铺只定三档尺寸,并写进团队手册:

用途 尺寸 命名后缀
列表缩略图 800×800 _s
详情主图 1200×1200 _m
手机端小图 600×600 _xs

命名规范示例:SKU12345_s_01.jpg、SKU12345_m_01.jpg。其中 SKU12345 是商品编码,s 是尺寸档,01 是序号。好处很实在:按文件名排序就是按商品、按尺寸、按序号排序;客服、美工、运营传文件时不会互相覆盖;上架系统按规则批量导入也不会认错图。

文件名里不要出现空格、中文括号和特殊符号。相机导出的 IMG_20261111 (1).jpg 这类名字,先统一重命名再处理,否则后续上传到不同平台时,个别系统会对空格和括号做转义,链接容易断。

二、核心思路:等比缩放 + 白底居中,而不是硬拉伸

商品图最忌讳硬拉伸。把一张 3:2 的横图直接压成 1:1 的方图,商品会明显变胖,买家一眼就能看出来。正确做法分三步:先按 EXIF 信息把照片方向摆正,再等比缩小到目标框内,最后把图片居中贴到一张纯白底的方形画布上。这样无论原图是横是竖,出来的缩略图都是统一尺寸,商品不变形,四周留白也整齐。

另外注意两点:第一,PNG 透明图转 JPG 时要先铺白底,否则透明区域会变成黑色;第二,保存 JPG 时质量取 85 左右,体积通常能比质量 95 小一半以上,手机端加载更快,肉眼几乎看不出差别。

三、环境准备

只需要 Pillow 一个库:

pip install Pillow

建议用 Python 3.10 以上版本。脚本不依赖任何在线服务,图片全部在本地处理,商品原图不会上传到第三方。

四、核心代码:单张图生成缩略图

from pathlib import Path
from PIL import Image, ImageOps


def make_thumbnail(src: Path, dst: Path, size=(800, 800), quality=85) -> Path:
    """把一张图等比缩放后居中贴到白底画布上,保存为 JPG。"""
    with Image.open(src) as im:
        # 1. 按 EXIF 方向摆正,手机拍的竖图不会横过来
        im = ImageOps.exif_transpose(im)
        # 2. 透明图先铺白底,再转 RGB,避免转 JPG 后变黑底
        if im.mode in ("RGBA", "LA", "P"):
            background = Image.new("RGB", im.size, (255, 255, 255))
            alpha = im.convert("RGBA").split()[-1]
            background.paste(im.convert("RGBA"), mask=alpha)
            im = background
        else:
            im = im.convert("RGB")
        # 3. 等比缩小到目标框内,不拉伸
        im.thumbnail(size, Image.LANCZOS)
        # 4. 居中贴到白底方形画布上
        canvas = Image.new("RGB", size, (255, 255, 255))
        x = (size[0] - im.width) // 2
        y = (size[1] - im.height) // 2
        canvas.paste(im, (x, y))
        dst.parent.mkdir(parents=True, exist_ok=True)
        canvas.save(dst, "JPEG", quality=quality, optimize=True)
    return dst

thumbnail 是 Pillow 里最省事的方法:它只缩小不放大,原图比目标小也不会被强行拉大,避免模糊。Image.LANCZOS 是高质量缩放算法,处理商品细节图时边缘更干净。

五、批量代码:按命名规范一次处理整个文件夹

SIZES = {"s": (800, 800), "m": (1200, 1200), "xs": (600, 600)}


def batch_thumbnails(src_dir: str, dst_dir: str) -> None:
    src_root = Path(src_dir)
    dst_root = Path(dst_dir)
    for src in sorted(src_root.rglob("*.jpg")) + sorted(src_root.rglob("*.png")):
        # 原图命名示例:SKU12345_01.jpg,取第一段当作商品编码
        stem = src.stem
        parts = stem.split("_")
        sku = parts[0] if parts else stem
        seq = parts[1] if len(parts) > 1 else "01"
        for tag, size in SIZES.items():
            dst = dst_root / f"{sku}_{tag}_{seq}.jpg"
            if dst.exists():
                print(f"跳过已存在:{dst.name}")
                continue
            make_thumbnail(src, dst, size=size)
            print(f"已生成:{dst.name}  {size[0]}x{size[1]}")


if __name__ == "__main__":
    batch_thumbnails("./原图", "./缩略图")

运行后,./原图/SKU12345_01.jpg 会同时生成 SKU12345_s_01.jpg、SKU12345_m_01.jpg、SKU12345_xs_01.jpg 三张图,分别放在 ./缩略图 文件夹里。脚本会跳过已经生成过的文件,第二次运行只处理新增图片,适合每天到货一批新品就跑一次。

六、五个常见坑

第一,手机拍的图方向错乱:不加 ImageOps.exif_transpose,竖拍的商品图在网页上会横过来,这一步不要省。第二,PNG 转 JPG 变黑底:透明通道必须先铺白底再转 RGB。第三,CMYK 模式的印刷图:直接保存 JPG 可能偏色,先 convert("RGB") 再处理。第四,文件名含空格或中文括号:批量上传前先统一重命名,规则越简单越不容易出错。第五,原图只有几百 KB 却生成了几 MB 的缩略图:通常是质量参数写成了 100,或者原图是无损 PNG,保存时把 quality 控制在 80 到 90 之间即可。

七、验收清单

跑完脚本后抽查三件事:一是打开三档图片,确认商品没有拉伸变形,四周留白均匀;二是检查文件大小,800 图一般在 80KB 到 200KB 之间,超过 500KB 就要看一下质量参数;三是按文件名排序,确认同一商品的三档图排在一起,序号连续。

这套脚本我在线上店铺用了两个月:每天上新 30 到 50 个商品,缩略图处理从原来一小时的手工操作压缩到三分钟跑完脚本加五分钟抽查。规则先定好、代码只做规则的执行者,图片这件事就不会再占用运营每天的整块时间。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。