同样一句“细长的秋叶”,人脑里可能是柳叶,模型却可能画成枫叶。继续堆风格词有时能改善气氛,却没有解决形状歧义。我会先画一张最简参数草图,把长宽、中脉和轮廓交代清楚,再让模型提颜色、纸张和构图方案。
参考图能约束什么
Google 的 Nano Banana 2.1 模型页介绍了参考图融合与图像编辑能力。对创作工具,这意味着草图可以成为输入材料;它没有承诺参数会被逐像素遵守。原始 SVG 和生成结果需要分开留存,轮廓是否偏离仍由人核对。
内图标注的是参数含义,并非按 160/48 等比测绘;下面的 SVG 才直接使用这些数值。下面只生成一枚对称叶片:长度 L、半宽 W,以两段三次 Bézier 曲线围合。它没有描述叶子的失水、组织结构或真实生长规律。控制点横向偏移设为4W/3,是因为本段曲线中点的偏移为控制点偏移的四分之三,最终中部半宽才接近 W。参数名若写“半宽”,计算就应该兑现这个含义。
参数卡应随图保存
导出时在desc中保留参数,可以减少后来“这片叶子怎么画出来的”的猜测。若接入 AI 编辑,任务卡还应写明哪些形状必须保留,哪些地方允许自由发挥,例如“不改变叶尖和长宽比,允许修改纸纹与配色”。模型最终仍可能偏离,参数卡提供的是比对基准。
运行node leaf.js会得到leaf.svg,并检查尺寸拒绝与曲线中点。路径命令的含义可对照 SVG 2 路径规范。本地只验证了几何计算与文本导出,未测试绘图模型、浏览器字体或实体印刷。
把形状说清楚以后,创作并没有变窄。它只是让讨论从“更像一片叶子”变成“保留这条轮廓,再试一种光”。这种小而明确的参照,很适合独立工具。
可独立运行的核心例子
const fs=require('node:fs'); function leaf(L,W) { if(!Number.isFinite(L)||!Number.isFinite(W)||L<20||L>500||W<2||W>L/2) throw Error('L需20..500,W需2..L/2'); const c=4*W/3, cx=c+12, top=12, bottom=top+L; const d=`M${cx},${top} C${cx+c},${top+L/3} ${cx+c},${top+2*L/3} ${cx},${bottom} C${cx-c},${top+2*L/3} ${cx-c},${top+L/3} ${cx},${top} Z`; return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${2*cx} ${L+24}"> <desc>叶片长度${L},中部半宽${W};参数化示意</desc> <path d="${d}" fill="#bfcb92" stroke="#617354"/> <path d="M${cx},${top} L${cx},${bottom}" stroke="#617354"/> </svg>`; } const cubic=(a,b,c,d,t)=>(1-t)**3*a+3*(1-t)**2*t*b+3*(1-t)*t*t*c+t**3*d; if(Math.abs(cubic(0,64,64,0,.5)-48)>1e-9) throw Error('半宽错误'); let rejected=false;try{leaf(100,80);}catch{rejected=true;} if(!rejected) throw Error('错误尺寸应拒绝'); fs.writeFileSync('leaf.svg',leaf(160,48)); console.log('已导出 leaf.svg,L=160,W=48');