做跨境电商的人应该都有过这个体验:在1688上挑产品时觉得图片还挺好看,但真要把这套图搬到亚马逊,心里就开始打鼓。中文促销横幅、店铺水印、工厂Logo,还有各种“亏本清仓”“工厂直销”的角标,直接传上去轻则被系统警告,重则整个链接被下架。标题里说的“一键清洗”与汉化,本质上就是把一张“中文电商图”变成符合亚马逊规范的白底英文主图。这篇文章我打算把整套用 Python+AI 实现的流程拆开讲:从抠图、擦字、生成白底,到 OCR 识别中文并翻译成英文重新排版,每一步都带上代码和实操中踩过的坑。适合三类人看:被图片合规逼疯的运营、想把手动 PS 流程自动化的开发者、以及刚入门跨境电商还在用手抠图的卖家。
1. 先搞清楚:为什么1688的图不能直接搬上亚马逊
1.1 亚马逊图片规范与1688原图的四个核心冲突
其实很多人不是不知道亚马逊对主图有要求,而是不清楚这条规则到底有多硬。亚马逊的主图必须满足:纯白背景(RGB 255,255,255)、产品占图片的85%左右、不能有文字水印Logo边框拼图,也不能出现促销信息、同一产品的多角度合成图、以及任何非在售商品的道具。JPEG、TIFF、PNG 都可以用,但建议边长至少 1600px,这样买家缩放的时候图片不会糊。这些条件单独看都不苛刻,但放在 1688 的图库里,几乎每一张都是“违章”。
我把 1688 原图的问题归纳成四类,这四类直接影响上架审核和点击率。第一类是供应商信息水印,比如店铺名、联系方式,通常半透明贴在角落;第二类是促销文案,像“限时特惠”“亏本清仓”“工厂直销”,又大又显眼,还带描边和渐变,比产品本身还抢眼;第三类是背景杂乱,有拍摄场景、道具、其他产品,甚至还有色块和插画;第四类是中文标注,比如产品参数的介绍文字、材质说明,这些不是不能用,但需要本地化成英文才能在亚马逊上正常展示。
| 维度 | 亚马逊要求 | 1688常见情况 |
|---|---|---|
| 背景 | 纯白 RGB(255,255,255) | 各种实景、渐变、色块 |
| 文字 | 主图不允许任何文字 | 大面积中文促销文案 |
| 水印 | 完全禁止 | 店铺名 / 联系方式 / Logo |
| 构图 | 单主题占85%区域 | 拼图、多角度、多配件 |
| 尺寸 | 推荐1600px以上 | 普遍1000px左右 |
这类图直接传上去的后果,轻则图片审核不通过,重则链接被标记为违规,甚至影响账户状况。而且从转化角度看,一张满是中文横幅的图,欧美买家第一眼根本不知道产品长什么样。所以说“一键清洗”不是懒人偷工,而是上架前的刚需。
1.2 人工修图的真实成本与自动化切入点
很多人听到“清洗 + 汉化”的第一反应是:这不是用 PS 手动修就行吗?单个产品当然可以。但跨境选品不是一次处理一张图,一次选品会议可能过几十个款式,每个款式还有主图、辅图、细节图要处理,靠设计师一张一张抠图,一套图少说半小时,多则一两个小时。遇到那种满屏促销文字的产品图,光是擦文字再补背景就要磨半天。
我算过一笔账:一个十人左右的小团队,如果每周上新 20 个 SKU,每个 SKU 处理 5 张图,就有 100 张图要处理,人工修图时间按每张 15 分钟算,光图片环节每周就吃掉 25 个小时。这个成本对小团队来说非常可观。自动化的切入点就在这张图处理的重复劳动上:背景剔除、文字擦除、白底合成、中文识别、翻译排版,这五个步骤本质上都是模式化操作,完全可以交给 Python + AI 来完成。
当然,自动化不是要完全取代人,而是把人从重复劳动里解放出来,让人只做最后的质量审核和异常处理。我后面讲的这套流程,也采纳的是“机器批量处理 + 人工抽检兜底”的思路。
2. 整体方案设计:把图片处理拆成一条流水线
2.1 五步流水线的模块划分
整套流程我拆成五步,每一步都能独立跑,也能串成一个 Python 脚本。第一步是输入,把 1688 的商品图下载保存到本地目录,可以手动下载,也可以结合电商采集脚本;第二步是清洗,先用分割模型把产品主体从原图中抠出来,再把背景上的文字和 Logo 擦掉;第三步是合成,把干净的产品合成到纯白底上,按亚马逊主图比例裁剪居中;第四步是汉化,对图中中文内容做 OCR 识别,翻译成英文;第五步是排版输出,把英文卖点按预设模板重新排到图上,导出多尺寸文件。
我之所以坚持“先清洗、后汉化”的顺序,是因为这两件事面对的是同一批像素。如果先汉化再清洗,中文翻译后的英文字会被当成噪音一起擦掉,等于白干。反过来,先清洗背景和杂物,再在干净的图上叠加英文文案,逻辑就顺了。这也是整个流程设计里最容易踩的坑之一。
2.2 技术选型与关键考量
Python 是整条流水线的胶水语言,生态太全了。图像处理用 Pillow 和 OpenCV,背景分割用 rembg(背后是 U2-Net 模型),文字检测用 PaddleOCR,图像修复用 OpenCV 自带的 inpainting 或者 LaMa 模型。翻译环节我建议先用通用的机器翻译 API 跑通流程,之后再根据效果决定要不要上大模型。
这里选型背后有几个考量。第一,隐私和成本。商品图涉及选品数据,全走外部 API 可能泄露和费钱,所以分割和 OCR 优先在本地跑,翻译才走 API。第二,精度和速度的平衡。rembg 在普通 CPU 上处理一张 1200x1200 的图大约三四秒,算可以接受;如果上了 GPU,速度还能再降。第三,错误率可控。所有模型都不是 100% 准确,所以流程里预留了人工复核环节——凡是置信度低于阈值的结果,统一放到一个待审核文件夹,由人来看看。
另外一个设计原则是“一个环节只做一件事”。不要试图让一个模型同时完成抠图和擦字,多任务模型在开源工具链里还不够成熟,硬凑在一起只会让故障排查变得非常痛苦。拆成独立模块,每个模块出问题可以单独替换,代码维护成本低得多。
3. 商品图清洗的代码实现:抠图、擦字、白底一气呵成
3.1 背景剔除的落地细节
背景剔除是整个流程里最成熟的一环。用 rembg 很简单,但我实际跑下来有几个细节需要提。
先给基础代码:
import rembg from PIL import Image def remove_background(input_path: str, output_path: str): with open(input_path, "rb") as f: input_data = f.read() output_data = rembg.remove(input_data) with open(output_path, "wb") as f: f.write(output_data) img = Image.open(output_path).convert("RGBA") white_bg = Image.new("RGBA", img.size, (255, 255, 255, 255)) white_bg.paste(img, (0, 0), img) white_bg.convert("RGB").save("white_bg.jpg", quality=95)第一次运行它会自动下载模型文件,大约 170MB,如果公司网络受限会卡住,建议提前把模型文件放到~/.u2net目录。其次,u2net 对“产品与背景颜色相近”的情况非常头疼,比如白色充电器放在白色桌面上,抠出来经常是一团白,什么也没有。我的解决办法是先对原图做一次轻度对比度拉伸,或者改用 isnet-general-use 模型再试。
另外,输出格式上有个隐性坑:JPEG 不支持透明通道,如果直接把 RGBA 的 PNG 存成 JPG,透明部分会变成纯黑色背景,等于白干。所以要先贴白底、转成 RGB,再另存为 JPEG。
3.2 文字与Logo区域检测和擦除
清洗的第二件事是擦掉水印和促销文字。这里的关键不是“把字盖掉”,而是“把字下面的背景还原出来”。我的方案分三步:第一步用 PaddleOCR 定位所有文本区域,得到每个文字块的四个角点坐标;第二步根据坐标生成一个覆盖文字的 mask;第三步对 mask 区域做图像修复(inpainting)。
代码如下:
import cv2 import numpy as np from paddleocr import PaddleOCR ocr = PaddleOCR(use_angle_cls=True, lang="ch", show_log=False) result = ocr.ocr("product_raw.jpg", cls=True) img_bgr = cv2.imread("product_raw.jpg") height, width = img_bgr.shape[:2] mask = np.zeros((height, width), dtype=np.uint8) for line in result: for word_info in line: box = np.array(word_info[0], dtype=np.int32) cv2.fillPoly(mask, [box], 255) # 膨胀,防止文字边缘残留 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) mask = cv2.dilate(mask, kernel, iterations=2) clean = cv2.inpaint(img_bgr, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)这里有个很重要的参数,inpaintRadius。数值太大会让修复区域糊成一片,丢失纹理;太小又盖不住笔画的边缘。我一般取 3 到 5 之间。另外,PaddleOCR 对大段艺术字和带描边的特效字识别不稳定,可能漏检。我的补救手段是先把原图锐化一遍再做 OCR,能把识别率提上来一截。
3.3 白底图生成与尺寸归一化
清洗完之后就是合成白底图。亚马逊主图要求产品占图片面积的 85% 左右,这个比例不是精确计算出来的,但至少不能让主体显得太小。按这个思路,把抠出来的产品粘贴到白底上之后,需要检测产品轮廓的包围盒,再按包围盒尺寸整体放大或缩小到原图宽度的 85%。
核心逻辑:
from PIL import Image def fit_product_to_white_bg(img_nobg: Image.Image, target_ratio: float = 0.85) -> Image.Image: bbox = img_nobg.getbbox() if bbox is None: raise ValueError("产品或背景未能正确分离") cropped = img_nobg.crop(bbox) scale = target_ratio * min(img_nobg.size) / max(cropped.size) new_w = int(cropped.width * scale) new_h = int(cropped.height * scale) resized = cropped.resize((new_w, new_h), Image.LANCZOS) canvas = Image.new("RGBA", img_nobg.size, (255, 255, 255, 255)) canvas.paste(resized, ((canvas.width - new_w) // 2, (canvas.height - new_h) // 2), resized) return canvasgetbbox()会返回非透明区域的最小矩形,但它对半透明边缘的容忍度很差,边缘毛糙时会把一个杂点也算进去。我常配合一个“去杂点”操作:先二值化 alpha 通道,把孤立的小区域清掉,再来计算包围盒。尺寸方面,最后统一导出 1600x1600,这是亚马逊侧边栏能正常显示缩放的最小稳妥值。
4. 汉化不是翻译,而是重新排版
4.1 OCR识别与翻译链路
汉化之前先想清楚一件事:主图上到底该不该放文字?按照亚马逊的规则,主图是不能有文字的。所以你清洗出来的图上如果还有中文,直接删掉即可,根本不需要翻译。真正需要汉化的,是那些放在副图里的“功能说明图”“尺寸图”“卖点图”。
先说识别链路。PaddleOCR 识别中文的效果在开源模型里算第一梯队。跑一次 OCR,不仅能拿到文字内容,还能拿到每个文字区域的位置和置信度。这一步要做的不仅仅是“认字”,更重要的是把“哪段文字属于可翻译内容”和“哪段文字属于纯噪音(水印、店铺名)”区分开。我的经验是维护一个过滤词表,把“工厂”“批发”“微信”“电话”“包邮”这类词直接归类为噪音,不进翻译流程。
翻译这一步,我用的是通用机器翻译 API,申请账号后拿到密钥,调用标准接口即可。这里有个经验:中文电商文案里的夸张词,像“全网最低”“顶级材质”“全网第一”,直译成英文不仅生硬,还有广告违规风险。我通常在翻译之前先做一次“文案净化”,把夸张词替换成中性词,比如“顶级”换成 premium,“销量第一”直接删掉。这一步很小但非常关键。
4.2 英文文案排版与“过度汉化”问题
翻译完成的英文文案,要动态排回图上。用 Pillow 排文字,关键难点是字号自适应。中文字体一个字占一个方块,宽度非常规整,但英文单词长度差异极大,同一个 box 里可能塞得下 ok 却塞不下 waterproof。所以在渲染时,我都是先按预设字号算一遍 textlength,如果宽度超出文字框,就逐级缩小字号,直到放得下为止。
from PIL import Image, ImageDraw, ImageFont def draw_text_in_box(canvas, box_left, box_top, box_right, box_bottom, text, font_path): draw = ImageDraw.Draw(canvas) max_width = box_right - box_left font_size = 48 while font_size > 12: font = ImageFont.truetype(font_path, font_size) w = draw.textlength(text, font=font) if w <= max_width: break font_size -= 2 draw.text((box_left, box_top), text, font=font, fill=(0, 0, 0))我这里说的“过度汉化”,指的是一个很容易犯的方向性错误:看到图上有任何中文都想翻译。实际上,很多中文标注是纯装饰性的宣传语,比如“你值得拥有”,翻译过去既无信息量,又有违规风险;还有一些中文对应的英文卖点在亚马逊文案里已经有了,图上不需要再放。真正值得保留和翻译的,是产品参数类说明,比如容量、尺寸、材质、防水等级、接口类型。做这套工具的时候,最好先和运营对一遍“哪些信息必须上图”,再定翻译规则,不然后期返工率极高。
5. 实操中踩过的最深的几个坑
5.1 边缘发毛与主体丢失
rembg 抠出来的图,遇到绒毛类、透明玻璃类产品,边缘经常是一圈半透明的毛边。直接贴白底,边缘会有白蒙蒙的一圈,在深色背景的主图上尤其明显。解决办法是后处理:把 alpha 通道做一次最小值滤波,然后再做轻微腐蚀,把透明像素“咬掉”一圈。
另一种更严重的情况是主体直接丢失。白色产品配白色背景,模型容易把产品当成背景一起抠掉,输出全透明图。这个问题的排查不能只靠肉眼看几张图,要在流程里加一个“全透明比例检查”:统计 alpha 通道为 0 的像素占比,超过阈值就自动把这张图丢到待人工处理列表,不要悄悄继续往下跑。
5.2 文字擦除后的背景断裂
inpaint 擦掉文字后,背景如果是渐变或者有纹理的,修复区域经常会留下一块光秃秃的“补丁”。最典型的就是促销文案压在彩色渐变背景上,擦完以后渐变没了,出现一块纯色。这个问题靠调参解决不了,方向是换更聪明的修复模型。我后来把 OpenCV 的 inpaint 换成了 LaMa 这个专门做图像修复的模型,它在大面积修复上的效果明显比传统算法自然。
用 LaMa 时,mask 之外还要保证输入尺寸满足模型要求,一般是 256 的倍数,不满足就做 padding,别直接 resize,否则文字区域坐标会错位,修复结果和原图对不上。
5.3 高分辨率大图与内存问题
1688 高清图动辄 4000x4000 像素,直接整张喂给模型,CPU 上慢得离谱,GPU 上也经常爆显存。我的处理策略是先降到 1024 或 1280 做推理,拿到分割 mask 之后再把 mask 放大回原尺寸,再拿去抠图。这样既能保留原图的清晰度,又能让模型推理跑得动。
但要注意,mask 放大之后边缘会变硬,直接套在原始高分辨率图上,边缘会产生一圈锯齿。解决办法是对放大后的 mask 做一次高斯模糊,让过渡更平滑。这个细节不要省,否则高分辨率输出时瑕疵会被放得很大。
5.4 颜色空间与格式混用
OpenCV 读图默认是 BGR,Pillow 是 RGB,两个库混用的时候最容易出偏色问题。比如我先把图读成 BGR,做完 inpaint 又用 Pillow 打开一次,最后保存出来的图整体偏蓝偏红,找半天才发现是通道顺序反了。现在的习惯是统一用 Pillow 读写,中途需要 OpenCV 处理时就先用 cvtColor 转一次,处理完再转回 RGB。另外,JPEG 不支持透明通道,PNG 不支持带 ICC 的 CMYK,这两个格式问题也踩过,批量脚本里最好做一次格式校验。
6. 这套方案的边界与后续扩展
6.1 哪些商品不适合自动清洗
先泼一盆冷水:这套流程最适合的是“标品 + 简单背景”的图,比如数码配件单品、杯具、小家电。一旦遇到模特穿戴图、复杂场景图、玻璃反光产品,自动处理的失败率会明显上升。模特图涉及人像分割和身体结构,普通产品分割模型根本搞不定;玻璃反光产品在抠图时很容易把高光区域当成背景,导致产品缺一块。所以我的建议是把它定位成“人机协作流水线”,机器负责能干的粗活,人负责审核和疑难杂症,这才是最稳的生产方式。
6.2 值得投入的扩展方向
扩展方向有几个我很看好的。一是批量任务调度,把脚本改造成监听文件夹的模式,运营把图丢进一个目录,程序自动处理后输出到另一个目录,配合日志和异常告警,基本就是一个轻量级的中台。二是把处理前后的图拼成对比图,方便人工抽检和存档,出了问题也能追溯是哪一步处理导致的。三是后续接入 AI 生成场景图,把清洗干净的白底产品喂给生成模型,自动产出符合当地审美的场景图,这个方向一旦跑通,价值会比单纯清洗高很多。
整套流程跑通之后,我最直观的感受是:不要追求“一个按钮全搞定”的幻想,也不要低估人在这个流程里的价值。自动化省下来的是重复劳动的时间,但图片是否符合审美、是否踩到平台规则,最后还是得靠有经验的眼睛来把关。这也是我做完这个项目之后最大的体会。