电商图片批量处理实战:Python+Pillow 一键完成裁剪、压缩、水印与格式转换

做电商或给小程序商城上架商品时,最繁琐的往往不是写文案,而是处理图片:几十上百张原图尺寸不一、体积过大、格式混乱,平台又要求主图统一为 800×800、详情页宽度固定,还得加上自己的 Logo。手工一张张改既慢又容易出错。

这类高度重复的工作适合交给脚本。本文用 Python 的 Pillow 库,给出一套可直接运行的批量处理方案,覆盖统一尺寸(不变形)、压缩到指定体积、添加水印、多规格导出、格式转换五个常见需求。

环境准备

bash 复制代码
pip install Pillow

建议使用 9.x 以上版本。下面所有示例基于 Pillow 的 Image 模块。

一、统一主图尺寸:等比缩放 + 白底填充

直接 resize 到 800×800 会把长方形商品图拉变形。正确做法是先等比缩放,再居中贴到正方形白底画布上:

python 复制代码
from PIL import Image

def fit_square(im, size=800, bg=(255, 255, 255)):
    im = im.convert("RGB")
    im.thumbnail((size, size), Image.LANCZOS)   # 等比缩放,不超过目标尺寸
    canvas = Image.new("RGB", (size, size), bg)
    x = (size - im.width) // 2
    y = (size - im.height) // 2
    canvas.paste(im, (x, y))
    return canvas

thumbnail 是原地等比缩放,LANCZOS 重采样在缩小时画质较好。需要透明背景的 PNG 场景,可把 bg 换成透明并使用 RGBA 模式。

二、批量压缩并控制体积

商品图过大不仅上传慢,也会拖慢商城页面加载。下面的函数通过循环降低质量,把文件压到目标体积以内,同时设了质量下限避免糊图:

python 复制代码
import os

def save_under(im, path, limit_kb=300, quality=90):
    while quality >= 55:
        im.save(path, "JPEG", quality=quality, optimize=True)
        if os.path.getsize(path) <= limit_kb * 1024:
            return quality
        quality -= 10
    return quality

照片类用 JPEG;含大量文字、Logo 或需要透明的图用 PNG。两者不要混用:照片存成 PNG 体积会明显变大。

把 Logo 等比缩放到画面宽度的约 18%,贴在右下角并留边距:

python 复制代码
def add_watermark(base, logo_path, margin=24):
    base = base.convert("RGBA")
    logo = Image.open(logo_path).convert("RGBA")
    logo.thumbnail((int(base.width * 0.18), int(base.height * 0.18)))
    layer = Image.new("RGBA", base.size, (0, 0, 0, 0))
    x = base.width - logo.width - margin
    y = base.height - logo.height - margin
    layer.paste(logo, (x, y), logo)          # 第三个参数做透明遮罩
    return Image.alpha_composite(base, layer).convert("RGB")

四、一次输出多种规格

同一张原图常需同时产出主图、详情页首图、朋友圈图等。用"规格表"驱动,避免为每个尺寸写一遍逻辑:

python 复制代码
SPECS = {
    "main":   (800, 800),
    "detail": (790, 790),
    "feed":   (1080, 1080),
}

def export_specs(im, out_dir, name):
    for tag, (w, h) in SPECS.items():
        out = fit_square(im, max(w, h))
        out = out.resize((w, h)) if (w, h) == (h, w) else out
        out.save(os.path.join(out_dir, f"{name}_{tag}.jpg"),
                 "JPEG", quality=85, optimize=True)

五、批量遍历整个目录

把上面的能力串起来,遍历源目录、跳过非图片、按原文件名输出:

python 复制代码
SRC = "products"
DST = "out"
os.makedirs(DST, exist_ok=True)

for fn in os.listdir(SRC):
    if fn.lower().endswith((".jpg", ".jpeg", ".png", ".webp", ".bmp")):
        im = Image.open(os.path.join(SRC, fn))
        name = os.path.splitext(fn)[0]
        main_img = fit_square(im)                 # 统一主图
        # main_img = add_watermark(main_img, "logo.png")  # 需要水印时打开
        save_under(main_img, os.path.join(DST, name + ".jpg"), limit_kb=300)
        print("done:", fn)

图片量很大(上千张)时,可用 concurrent.futures.ThreadPoolExecutor 把每张图的处理放进线程池, Pillow 释放 GIL 的环节能获得一定加速;注意控制并发数避免磁盘 IO 打满。

小结

整个流程的关键是三点:用"等比缩放 + 画布填充"而不是硬拉伸来保证不变形;用质量递减循环把体积压到平台要求内;用规格表 + 目录遍历实现一次配置、批量产出。把脚本保存下来,每次上新直接跑一遍即可,比手工处理稳定得多。

常见问题

电商主图尺寸一般是多少?

淘宝、京东、抖音小店多为 800×800(1:1),拼多多常见 750×750,具体以各平台当年的规则为准。

图片压缩后会不会变模糊?

照片用 JPEG、质量不低于约 75~80 通常肉眼差异很小;文字和 Logo 多的图建议用 PNG,避免出现锯齿。

批量处理时 PNG 透明背景怎么保留?

全程使用 RGBA 模式并导出为 PNG,不要转成 RGB/JPEG,否则透明区域会被填成实色。

相关推荐
高洁011 小时前
AI视频生成技术:从静态图文到动态视觉的内容智能革命
python·深度学习·django·transformer·tornado
沐欣工作室_lvyiyi1 小时前
基于Flask的旅游大数据分析与可视化系统(论文+源码)
python·flask·旅游
施棠海1 小时前
多 Agent 团队编排系统的设计与实测:agent-workflow
python·ai·架构
asdzx671 小时前
Python 实现从 URL 在线下载 PDF 文档教程
python·pdf
Bruce_Liuxiaowei2 小时前
元组与具名元组:把「第 3 个字段」变成「price」
数据结构·python·语法·元组
___波子 Pro Max.2 小时前
pip 管库,pipx 管工具:Python 依赖隔离的正确姿势
python
我的xiaodoujiao3 小时前
Django 基础知识详细图文教程 12-Django 模型定义与使用 2
后端·python·django
happylifetree11 小时前
Python09:核心语法-数据存储与运算-字面量
python