商品详情长图的自动生成:版块模板、要素抽取与版式约束的实现思路
一、先把"详情长图"这个对象定义清楚
电商详情页在数据结构上不是一张图。它更像一个竖直串联的有序列表:列表里每个元素是一个版块,版块之间共享同一个画布宽度,各自高度不等。导出成 PNG 只是最后一步渲染,真正的中间表示应该是那串节点本身。
这样一拆,问题就变成三个互相牵制的子问题:
· 序列:这条链上该有几个节点,每个节点承担什么语义角色
· 填充:每个节点需要哪些素材和文案,这些素材从商品原图里能不能读到
· 版式:节点内部怎么排,高度怎么定,相邻节点怎么避免视觉重复
三件事不能分开解。序列决定填充的需求清单,填充的可得性反过来卡住序列长度,版式约束又会否决掉某些序列组合。所以它不是一个"选模板"的动作,更像一次带约束的搜索。
顺带提一个工程细节:渲染是按版块切片的,一版一张,最后由前端拼接或后端纵向合成。切片的好处是单个版块可以单独重生成------改文案不用重跑整条链。代价是版块之间的留白必须由序列层统一指定,否则会出现拼接缝,也就是下面说的节奏断层。
二、版块序列:语义角色,不是固定模板
按"模板"理解,序列就退化成一份静态清单,那么任何输入都该得到同一个长度。但实测三组输入,输出长度分别是五、六、七,说明序列不是常量。
把节点抽象成"语义角色",情况就清楚了。一个版块真正携带的信息是"它负责回应哪一类疑问",而不是"它长什么样"。
bash
role answers requires
--------------------------------------------------------------
hero 我在看什么 主体抠图、标题
variant 我要哪一个(多值) 全部配色图
scene 我用在哪儿 使用环境线索
proof 它经不经得起用 动作 / 受力线索
material 手感与工艺 材质局部
structure 内部构造 可拆零部件
detail 做工细节 边缘、接缝局部
dimension 尺寸关系 正交视图
spec 参数查表 参数键值
上表里几个角色的出现条件是硬性的,不是风格选择。
`variant` 存在的前提是输入里有多个等价选项。抱枕只有一款花色,这个角色直接缺席;风扇给了三个配色,`variant` 就上浮到序列最前面。为什么必须最前------因为选型是横向分叉,往下看详情是纵向展开,两件事的心理成本完全不同。分叉没闭合就往下讲,后面所有内容都可能讲错对象。
`structure` 存在的前提是商品有"看不见但决定价值的内部件"。剪刀有刃口、铆钉、内衬之间的层级,能拆;抱枕是整体填充,拆不出层级,这个角色不成立,硬塞进去只会得到一张没有信息量的图。
角色之间还有依赖关系。`dimension` 依赖主体轮廓可以被正交重建;`spec` 依赖输入侧提供了参数事实。这两个角色的输入如果缺失,序列就只能缩短,不能靠猜补齐。
所以序列生成本质上是一次角色筛选:输入支持哪些角色就留下哪些,不支持的直接丢掉。屏数是筛选结果,不是配置项。
三、要素抽取:从原图能读到什么
原图承载的信息量决定了序列上限。比较稳定能读出来的大致有这几类:
· 品类与形态:主体轮廓、命名线索
· 配色枚举:白底多图输入时可以直接数出有几种
· 使用状态:画面里有没有手、有没有环境背景、有没有其他物件
· 材质线索:布纹、金属反光、塑料质感、纹理走向
· 结构线索:接缝、铰链、铆钉、分模线
读不出来的同样明确:真实尺寸、内部填充、参数表。这些只能由输入侧补齐,否则 `dimension` 和 `spec` 只能落空。
这里有个反直觉的结论:原图拍得好不好看,和它能抽取到多少结构信息,是两回事。
剪刀那张原图是三组里最随意的------木纹桌上一躺,角度还是歪的,连正经俯拍都不算。但它给到的结构线索最密:锯齿的齿形、手柄双色分模的位置、铆钉的连接点,全在画面里。反倒是抱枕那张构图最规整、光线最匀,能读出的结构线索最少,最后只能往"手感 + 细节"两个方向走。
抽取失败也要分情况处理。主体抠不出来属于致命失败,直接打回;材质线索缺失属于降级,可以把 `material` 合并进 `detail`;配色数判断不出来,`variant` 就退化成单色主图加一句颜色说明。降级的边界应该在序列层定死,不要在渲染阶段临时决定。
还有一点容易被忽略:单图输入和多图输入的抽取路径不一样。单图是生活实拍时,画面里天然带着环境、带着手、带着参照物,`scene` 和 `proof` 的角色线索可以顺带读出来;多图是白底棚拍时,环境信息被剥干净了,好处是配色和轮廓更干净,坏处是场景线索得靠品类先验去补。三组样本里,抱枕和剪刀是前者,风扇是后者,序列差异有一部分就是从这儿来的。
四、版式约束:单版内的三条硬线
单个版块内部,至少要守住三条线。
第一条是主体占比。低于阈值,用户在手机屏幕上认不出这是什么;高于阈值,文案没有落脚位。这条线和版块高度是耦合的,改动其一必须重算另一。
第二条是文字密度。详情页的阅读动作是拇指滑动,单屏停留时间在秒级。文案量过线之后,继续加字不会提升理解,只会被跳过。
第三条是安全区。不同版块拼接时,顶底留白要统一到同一套栅格,否则整条长图会周期性地出现停顿感------每滑一屏就撞一次墙。
三条线经常互相打架。想要大面积主体,文案就得压缩;想保文案,主体占比就得让。我的处理方式是把它当成优先级问题:`hero` 和 `variant` 优先保主体,`spec` 和 `dimension` 优先保文字,`scene` 和 `proof` 两者都要中等,靠留白换呼吸。按角色分配权重,比全局调一个参数稳。
五、序列级约束:相邻不能同构
单版各自合格,串起来照样难看。约束发生在序列层:
· 相邻两个节点不允许同属"局部特写"类。剪刀那次把锯齿特写和细节标注挨着放过,两个高饱和微距画面背靠背,读下来像在原地打转。
· `proof` 之后必须接一个信息型节点,不能又是情绪型。情绪连续两次,说服力会衰减。
· `variant` 必须早于 `scene`。理由在第二节说过,顺序颠倒等于对着错误的款式展开场景。
· 同一种构图方式在一条序列里重复出现的次数要有上限,超过就得换机位或换景别。
这类约束用规则表达比用打分表达更省事,因为它们的本质是"禁止",不是"更喜欢"。
六、为什么长度会在品类内收敛
把前面几节串起来,长度收敛这件事就解释得通了。
同品类商品在"可拆结构""多值选项""使用场景分裂程度"这三项上高度同构。抱枕类目换个花色、换个尺寸,角色集合几乎不变,长度就稳在五。风扇类目换个档位、换个外壳工艺,`variant` 和数显相关角色照样都在,长度稳在六。

跨品类就撑不住了。角色集合的差集可能有两三个,长度自然跳一下。七和五之间差的不是两张图,是两个能被回答的问题。
收敛也有边界。如果同品类里出现明显不同的形态------比如抱枕里混进一个带抱枕被的二合一------`structure` 会突然成立,长度立刻偏离。判断"同品类"时不能只看类目名,要看这三项结构特征是否一致。
最常踩的坑是把长度当可调参数。我试过手工删角色把剪刀压到五,结果 `proof` 位置空出来,只好用 `detail` 顶上,正好触发第五条里那个相邻同构约束,整条链读起来是断的。

七、小结
把详情长图当成"有序节点列表 + 每个节点一份要素契约 + 一组版式与序列约束"来处理,比当成"套模板出图"更接近真实情况。模板在这里只解决"某一版内部怎么排",它解决不了"该有几版"。
雨林凯AI 的官方博客里有几篇同类讨论,可以当背景补充看。