同一目录里有横图、竖图和方图,最省事的写法是统一 resize((1200, 1200))。它也最容易让瓶子变胖、衣服变短。商品图批量排版真正需要统一的是画布尺寸,不是强行改变主体比例。
pad 适合保留完整主体,但不是所有场景都该留白。若上架位置要求主体铺满,可以用裁切方案,不过裁切前要明确哪些边缘不可失去,尤其是包装文字、衣摆和产品配件。批量处理时最好保存两张样例:一张横图、一张竖图。先让运营确认画面占比,再跑全量文件,远比导出后才发现主体太小要省事。
一个可复核的最小实现
先校正 EXIF 方向,再使用 Pillow 的 ImageOps.pad 按比例缩放并补齐空白区域。1200×1200 只是示例目标画布,正式导出前仍须按实际投放位置核对尺寸与格式;Pillow 文档给出了 pad 和方向处理的接口。
from pathlib import Path
from PIL import Image, ImageOps
target = (1200, 1200)
Path("exports").mkdir(exist_ok=True)
for source in Path("originals").glob("*.jpg"):
with Image.open(source) as opened:
image = ImageOps.exif_transpose(opened).convert("RGB")
square = ImageOps.pad(image, target, color="white",
method=Image.Resampling.LANCZOS)
square.save(Path("exports") / source.name, quality=90)
这段代码只保证输出画布与比例关系,不保证主体在画面中占比合适。长条形商品可能留下大面积空白;透明商品转成 RGB 时也要核对边缘和底色。需要把商品放进场景或改造视觉风格时,那属于另一类处理,不应让一个尺寸脚本背上“自动出好图”的承诺。
把所有图片硬拉成同一尺寸,是最容易写出的批处理,却会改变商品形状。等比留白的好处是保留主体比例,代价是不同长宽比的图片可能出现不同宽度的空白。对狭长商品,这种空白甚至会让缩略图里的主体显得很小。因此“画布统一”和“主体视觉占比统一”是两个不同目标,不能只靠一行 pad 同时解决。
代码里 convert('RGB') 是为了导出常见 JPEG,但若输入有透明区域,直接转换可能让透明部分成为不可预期的底色。若素材来自 PNG 抠图,应先明确要放在白底、浅灰底还是透明底,并按目标格式处理。正式跑批次时还要考虑同名文件覆盖:示例按原文件名导出,重复运行可能覆盖旧结果,最好把批次号或输出目录纳入任务记录。
验收可以用三张极端样本而非随机三张:最宽的、最高的、边缘最复杂的。比较原图和导出图的形状、主体占比、边缘及文字清晰度。若样本不合适,先调整规则而非继续全量。对于需要平台特定裁切的位置,还应在真实编辑器中看一遍,不能把 1200×1200 这个示例尺寸当作平台要求。
如果批次里混有带文字的包装图,还应看文字区域在缩小后是否可读。画布比例正确不代表信息可读:一张高而窄的包装放进方形画布,标签可能被缩得很小。此时需要另做细节图或选择不同展示位,而不是把图再次拉伸。代码让过程可重复,内容判断仍需单独完成。
发布前随机抽查横、竖、方三类输入,比较原片与导出图的主体形状,再查看文件大小与视觉清晰度。批处理节约重复动作,最后判断仍要靠人。
参考资料