商品图从 webp 批量转 png 上传,用的是 Pillow 10 的 img.convert('RGB').save(...),转完透明区域全变成纯黑,原图在浏览器里显示正常,设计的白色背景没了,运营以为是图片损坏。

一开始怀疑是「用 cv2.imread 读 webp 时默认忽略 alpha」,查了一圈,方向不对。

把日志和配置对完,能解释这个现象的基本就这几处。convert('RGB') 直接丢掉 alpha 通道,剩余像素按 0 填充成黑色。少数情况下是没有先合成到白底再转三通道。

还有一种情况,批量脚本复用了同一个 Image 对象,模式在循环里被改掉。

动手时先确认原图的模式与通道数

python -c "from PIL import Image;im=Image.open('a.webp');print(im.mode, im.size, 'A' in im.getbands())"

接着合成到白底再转 RGB

python -c "from PIL import Image;im=Image.open('a.webp').convert('RGBA');bg=Image.new('RGBA',im.size,(255,255,255,255));bg.alpha_composite(im);bg.convert('RGB').save('a.png')"

随后检查转换后角落像素值

python -c "from PIL import Image;print(Image.open('a.png').getpixel((0,0)))"

批量处理时每次重新打开文件

python -c "import glob;from PIL import Image;[Image.open(p).convert('RGBA').save(p.replace('.webp','.png')) for p in glob.glob('img/*.webp')]"

别只看报错消失,验证要多做一步。透明区域变成白色而不是黑色,转出的 png 在页面上的观感与 webp 一致,批量脚本抽查十张全部正常。

alpha 通道不能直接丢,丢之前要决定合成到什么底色,白底还是透明 png 取决于页面背景,这步想清楚能少返工一次。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189