fix: reduce scale adjust guide artifacts

This commit is contained in:
134 2026-06-25 00:05:52 +08:00
parent 270c9fb61d
commit acaae5fd1b

View File

@ -748,11 +748,8 @@ function buildScaleAdjustAnnotationSvg(params: {
const { width, height, regions, scalePercent } = params;
const minSide = Math.max(1, Math.min(width, height));
const strokeWidth = Math.max(2, Math.round(minSide * 0.0034));
const targetColor = "#008cff";
const sourceColor = "#e03131";
const connectorColor = "#667085";
const connectorWidth = Math.max(2, Math.round(strokeWidth * 0.72));
const markerSize = Math.max(7, Math.round(strokeWidth * 2.6));
const targetColor = "#111827";
const sourceColor = "#9ca3af";
const regionSvg = regions
.map((region) => {
@ -761,39 +758,10 @@ function buildScaleAdjustAnnotationSvg(params: {
const target =
region.targetPixelRect || rectToPixels(targetRect, width, height);
const radius = Math.max(8, Math.round(strokeWidth * 2));
const badgeSize = Math.max(22, Math.round(minSide * 0.022));
const badgeX = clamp(
source.left + Math.round(badgeSize * 0.45),
badgeSize / 2 + 4,
width - badgeSize / 2 - 4
);
const badgeY = clamp(
source.top + Math.round(badgeSize * 0.45),
badgeSize / 2 + 4,
height - badgeSize / 2 - 4
);
const fontSize = Math.max(13, Math.round(badgeSize * 0.52));
const sourceCenterX = source.left + source.width / 2;
const sourceCenterY = source.top + source.height / 2;
const targetCenterX = target.left + target.width / 2;
const targetCenterY = target.top + target.height / 2;
const centerDistance = Math.hypot(
targetCenterX - sourceCenterX,
targetCenterY - sourceCenterY
);
const connectorSvg =
centerDistance > Math.max(8, strokeWidth * 2.4)
? `<line x1="${sourceCenterX.toFixed(1)}" y1="${sourceCenterY.toFixed(1)}" x2="${targetCenterX.toFixed(1)}" y2="${targetCenterY.toFixed(1)}" stroke="${connectorColor}" stroke-width="${connectorWidth}" stroke-linecap="round" opacity="0.78" marker-end="url(#scale-adjust-arrow)" />`
: "";
return `
${connectorSvg}
<rect x="${source.left}" y="${source.top}" width="${source.width}" height="${source.height}" rx="${radius}" fill="${sourceColor}" opacity="0.04" stroke="${sourceColor}" stroke-width="${strokeWidth}" />
<rect x="${target.left}" y="${target.top}" width="${target.width}" height="${target.height}" rx="${radius}" fill="${targetColor}" opacity="0.055" stroke="${targetColor}" stroke-width="${Math.max(2, Math.round(strokeWidth * 1.05))}" />
<circle cx="${sourceCenterX}" cy="${sourceCenterY}" r="${Math.max(3, strokeWidth * 0.9)}" fill="${sourceColor}" opacity="0.88" />
<circle cx="${targetCenterX}" cy="${targetCenterY}" r="${Math.max(3, strokeWidth * 0.9)}" fill="${targetColor}" opacity="0.88" />
<circle cx="${badgeX}" cy="${badgeY}" r="${badgeSize / 2}" fill="${sourceColor}" opacity="0.9" stroke="#ffffff" stroke-width="${Math.max(1.5, Math.round(strokeWidth * 0.36))}" />
<text x="${badgeX}" y="${badgeY + fontSize * 0.36}" text-anchor="middle" fill="#ffffff" font-size="${fontSize}" font-family="Arial, Helvetica, sans-serif" font-weight="800">${region.index}</text>
<rect x="${source.left}" y="${source.top}" width="${source.width}" height="${source.height}" rx="${radius}" fill="none" stroke="${sourceColor}" stroke-width="${strokeWidth}" opacity="0.82" />
<rect x="${target.left}" y="${target.top}" width="${target.width}" height="${target.height}" rx="${radius}" fill="none" stroke="${targetColor}" stroke-width="${Math.max(2, Math.round(strokeWidth * 1.08))}" opacity="0.88" />
`;
})
.join("");
@ -802,11 +770,6 @@ function buildScaleAdjustAnnotationSvg(params: {
<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="${width}" height="${height}" fill="#f5f7fb" />
<rect x="${Math.max(1, strokeWidth / 2)}" y="${Math.max(1, strokeWidth / 2)}" width="${Math.max(1, width - strokeWidth)}" height="${Math.max(1, height - strokeWidth)}" fill="none" stroke="#d9dee8" stroke-width="${Math.max(1, Math.round(strokeWidth * 0.55))}" />
<defs>
<marker id="scale-adjust-arrow" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="${markerSize}" markerHeight="${markerSize}" orient="auto">
<path d="M 0 0 L 10 5 L 0 10 z" fill="${connectorColor}" opacity="0.86" />
</marker>
</defs>
${regionSvg}
</svg>
`);
@ -912,11 +875,11 @@ function buildScaleAdjustPrompt(
"这是一项局部主体比例 inpaint/edit 任务,不是整图缩放、整图裁切或重新构图任务。",
sourceSizeLine,
"输入图片1是原始干净图,也是最终输出必须继承的唯一画面基底。除目标主体尺寸变化与必要背景补全外,输入图片1中的文字、Logo、装饰、排版、背景、光线、构图边界和所有未选区域必须保持不变。",
"输入图片2是一张与输入图片1尺寸完全相同的坐标指令图,不是照片,也不是输出底图。它用灰色背景承载红色源框、蓝色目标框和中心移动箭头,只用于说明坐标关系;不得学习、复刻或输出其中的框线、箭头、编号、灰底或 UI 标记。",
"输入图片2是一张与输入图片1尺寸完全相同的灰度坐标指令图,不是照片,也不是输出底图。它只用细线源框和目标框说明坐标关系;不得学习、复刻或输出其中的线框、灰底或 UI 标记。",
cropLines
? `输入图片3及之后是框选区域的干净局部裁切参考图,作用是帮助你确认“要缩放的是哪个主体”。这些裁切图不是输出底图,不得被整体放大、贴回或覆盖到原图上。\n${cropLines}`
: "",
"输入图片2中的红色源框表示输入图片1里目标主体当前大致位置;它只用于定位主体,不限制调整后的空间。蓝色目标框表示用户希望主体调整后的视觉占位和中心位置,中心箭头只表示主体中心的移动方向。最终画面不得出现这些框线、箭头、编号或灰底;主体也不需要填满目标矩形,必须保持主体自身原始宽高比和透视形体。",
"输入图片2中的源框表示输入图片1里目标主体当前大致位置;它只用于定位主体,不限制调整后的空间。目标框表示用户希望主体调整后的视觉占位和中心位置。最终画面不得出现这些线框或灰底;主体也不需要填满目标矩形,必须保持主体自身原始宽高比和透视形体。",
"如果系统或模型只能读取一张参考图,必须优先以输入图片1为输出基底,不得清理、改写或删除输入图片1中框选区域外的任何文字和图形。",
"系统已根据用户框选区域计算出下方每个区域的原图坐标;框选区域只是定位目标主体的搜索范围,不是最终画面的裁切块、贴片、蒙版边界,也不是放大后的空间上限,更不是要整体缩放的矩形图层。",
"最终结果必须保持原始干净图的画幅比例、构图边界、镜头透视、光线、色温、材质质感和清晰度;严禁整张图整体缩放、裁切、平移、重新排版或重新生成。",
@ -931,9 +894,9 @@ function buildScaleAdjustPrompt(
"1. 只调整目标主体物体本身的整体视觉比例,不得保留原尺寸;主体轮廓宽度和高度必须同步等比变化,宽高比必须与原主体一致,不能为了贴合目标框而拉宽、压窄、拉高或压扁。",
"2. 严禁把整个矩形框选区域、输入图片1整张图或任意裁切图当成图片块整体缩放、平移、复制、裁切或贴回;最终画面不得出现矩形拼接边缘、色差硬边、补丁感、裁切线或局部贴片痕迹。",
"2.1 严禁把输入图片1整张图整体放大、缩小、裁切或重新构图;如果画面中的标题、Logo、页面文字、边框、窗框、背景家具或非目标主体发生整体位移/缩放/消失,必须视为失败并重新生成。请把这些元素当作像素锚点,它们的位置和比例不能跟着目标主体变化。",
"3. 如果输入图片2中的蓝色目标框明显小于红色源框,目标主体应自然变小,主体缩小后露出的背景、桌面、墙面、阴影、纹理和透视必须被重新生成并无缝补全,选区内应出现明显新增留白或背景。",
"4. 如果输入图片2中的蓝色目标框明显大于红色源框,目标主体应自然变大;允许主体自然超出用户手画的原始源框,使用周围真实背景完成边缘、阴影和遮挡衔接。宽度和高度都要同步变大,不能出现“高度变高但宽度变窄”的非等比变形;主体边缘与遮挡关系要合理,不能产生突兀裁切。",
"5. 如果蓝色目标框中心与红色源框中心不同,允许主体同步移动到蓝色目标框中心附近;如果主体靠近画布边界导致目标空间不足,请用能完整放入画面的最大统一倍率整体调整,绝不能为了塞进画面而只压缩宽度或只拉伸高度。",
"3. 如果输入图片2中的目标框明显小于源框,目标主体应自然变小,主体缩小后露出的背景、桌面、墙面、阴影、纹理和透视必须被重新生成并无缝补全,选区内应出现明显新增留白或背景。",
"4. 如果输入图片2中的目标框明显大于源框,目标主体应自然变大;允许主体自然超出用户手画的原始源框,使用周围真实背景完成边缘、阴影和遮挡衔接。宽度和高度都要同步变大,不能出现“高度变高但宽度变窄”的非等比变形;主体边缘与遮挡关系要合理,不能产生突兀裁切。",
"5. 如果目标框中心与源框中心不同,允许主体同步移动到目标框中心附近;如果主体靠近画布边界导致目标空间不足,请用能完整放入画面的最大统一倍率整体调整,绝不能为了塞进画面而只压缩宽度或只拉伸高度。",
"6. 框选区域内非目标主体的背景、墙面、桌面、植物、文字和其它物体应保持原场景逻辑,不要跟着主体一起缩放。",
"6.1 比例调整后的主体边缘必须和周围环境自然融合,选区边界不能被肉眼看出;不得出现一整块矩形区域清晰度、颜色、光照、纹理或透视突然变化。",
"6.2 框选区域通常会包含主体周围的背景留白,背景留白不是目标主体。请锁定这些非主体背景的窗框、文字、地毯纹理、墙面、桌面边缘和透视线,只重建主体缩放后被遮挡或露出的极小必要区域;不要把框选矩形当作整块背景重新生成。",
@ -1166,7 +1129,7 @@ export async function POST(request: NextRequest) {
annotatedReferenceUrl: annotatedUpload.url,
annotatedReferenceSentToModel: isScaleAdjustOperation,
annotatedReferenceType: isScaleAdjustOperation
? "scale-adjust-coordinate-guide-map"
? "scale-adjust-neutral-coordinate-guide-map"
: "source-overlay",
cleanSourceReferenceIndex: 1,
configuredDetailModelId: configuredDetailModel || null,
@ -1190,7 +1153,7 @@ export async function POST(request: NextRequest) {
scaleAdjustTargetRegionCount: regions.filter((region) => region.targetRect)
.length,
scaleAdjustPromptStrategy: isScaleAdjustOperation
? "locked-plate-coordinate-guide-map-pixel-anchors-v7"
? "locked-plate-neutral-coordinate-guide-map-pixel-anchors-v8"
: undefined,
scaleAdjustPostCompositeApplied: false,
scaleAdjustUsesFullFrameOutput: isScaleAdjustOperation,
@ -1207,7 +1170,7 @@ export async function POST(request: NextRequest) {
model: resolvedModel || undefined,
negativePrompt:
isScaleAdjustOperation
? "彩色框、蓝色边框、绿色边框、红色边框、橙色边框、矩形框、箭头、连线、角点、编号圆点、提示词气泡、标注文字、UI 控件、半透明色块、选区边框、白边、画幅压扁、画面拉伸、整张图缩放、全图放大、全图裁切、全图平移、整体重绘、删除文字、清理文字、改写文字、文字模糊、Logo消失、主体拉伸、主体压扁、主体变窄、主体变高但变窄、横向挤压、纵向拉伸、透视变形、矩形贴片、硬边、拼接线、补丁感、局部裁切、色差边缘、背景断裂、背景错位、窗框错位、文字错位、地毯纹理错位、非主体背景重绘、主体未缩放、整块框选区域缩放"
? "彩色框、蓝色边框、绿色边框、红色边框、橙色边框、矩形框、箭头、连线、角点、编号圆点、提示词气泡、标注文字、UI 控件、半透明色块、蓝色色块、色条、灰底坐标图、选区边框、白边、画幅压扁、画面拉伸、整张图缩放、全图放大、全图裁切、全图平移、整体重绘、删除文字、清理文字、改写文字、文字模糊、Logo消失、主体拉伸、主体压扁、主体变窄、主体变高但变窄、横向挤压、纵向拉伸、透视变形、矩形贴片、硬边、拼接线、补丁感、局部裁切、色差边缘、背景断裂、背景错位、窗框错位、文字错位、地毯纹理错位、非主体背景重绘、主体未缩放、整块框选区域缩放"
: "彩色框、蓝色边框、绿色边框、红色边框、橙色边框、矩形框、编号圆点、提示词气泡、标注文字、UI 控件、半透明色块、选区边框、白边、画幅压扁、画面拉伸、主体截断、动物截断、缺头、缺尾巴、缺四肢、贴边裁切、矩形贴片、硬边、拼接线、补丁感、色差边缘、背景错位、地面纹理断裂、椅脚错位",
prompt,
promptExtend: false,