diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts
index f465bf017..bfcc61267 100644
--- a/app/api/canvas/local-edit/route.ts
+++ b/app/api/canvas/local-edit/route.ts
@@ -729,6 +729,7 @@ function buildScaleAdjustPrompt(
`4. 放大时,目标主体应围绕原位置视觉中心自然变大到约 ${targetLabel};宽度和高度都要同步变大,不能出现“高度变高但宽度变窄”的非等比变形;主体边缘与遮挡关系要合理,不能产生突兀裁切。`,
"5. 如果主体靠近画布边界导致目标尺寸空间不足,请用能完整放入画面的最大统一倍率整体缩放;绝不能为了塞进画面而只压缩宽度或只拉伸高度。",
"6. 框选区域内非目标主体的背景、墙面、桌面、植物、文字和其它物体应保持原场景逻辑,不要跟着主体一起缩放。",
+ "6.1 比例调整后的主体边缘必须和周围环境自然融合,选区边界不能被肉眼看出;不得出现一整块矩形区域清晰度、颜色、光照、纹理或透视突然变化。",
"7. 未受比例调整影响的其它画面区域必须保持原图不变,尤其是框选区域外的文字、Logo、标题、尺寸标注、装饰条和页面排版不得被清理、改写、模糊或重绘。",
"8. 最终输出必须是一张完整、干净、无缝的照片,不得出现任何选区框、说明文字、对比线、比例数字或 UI 元素。",
"9. 输出前自检:如果目标主体大小与原图相比没有明显变化,或者主体宽高比发生非等比变形,必须重新生成;禁止返回看起来和原图相同或被拉伸的结果。",
diff --git a/lib/canvas/generate-image.ts b/lib/canvas/generate-image.ts
index c4cb34638..9e26919bc 100644
--- a/lib/canvas/generate-image.ts
+++ b/lib/canvas/generate-image.ts
@@ -112,8 +112,8 @@ class ScaleAdjustOutputRejectedError extends Error {
const LOCAL_EDIT_COMPOSITE_PADDING_RATIO = 0.14;
const LOCAL_EDIT_COMPOSITE_MIN_PADDING_RATIO = 0.012;
const LOCAL_EDIT_COMPOSITE_MAX_PADDING_RATIO = 0.06;
-const LOCAL_EDIT_COMPOSITE_FEATHER_MIN_PX = 10;
-const LOCAL_EDIT_COMPOSITE_FEATHER_MAX_PX = 44;
+const LOCAL_EDIT_COMPOSITE_FEATHER_MIN_PX = 18;
+const LOCAL_EDIT_COMPOSITE_FEATHER_MAX_PX = 72;
const SCALE_ADJUST_VISUAL_DIFF_THRESHOLD = 14;
const SCALE_ADJUST_OUTSIDE_DIFF_THRESHOLD = 18;
const SCALE_ADJUST_OUTSIDE_DIFF_MIN_CHANGED_RATIO = 0.28;
@@ -678,10 +678,10 @@ function buildLocalEditCompositeMaskSvg(params: {
LOCAL_EDIT_COMPOSITE_FEATHER_MIN_PX,
Math.min(
LOCAL_EDIT_COMPOSITE_FEATHER_MAX_PX,
- Math.round(Math.min(width, height) * 0.012)
+ Math.round(Math.min(width, height) * 0.018)
)
);
- const rects = regions
+ const rectEntries = regions
.map((region) => {
const left = Math.max(0, Math.round(region.x * width));
const top = Math.max(0, Math.round(region.y * height));
@@ -693,7 +693,33 @@ function buildLocalEditCompositeMaskSvg(params: {
height - top,
Math.max(1, Math.round(region.height * height))
);
- return ``;
+ return { left, top, rectHeight, rectWidth };
+ })
+ .filter(({ rectHeight, rectWidth }) => rectWidth > 0 && rectHeight > 0);
+ const softRects = rectEntries
+ .map(
+ ({ left, top, rectHeight, rectWidth }) =>
+ ``
+ )
+ .join("");
+ const coreRects = rectEntries
+ .map(({ left, top, rectHeight, rectWidth }) => {
+ const inset = Math.max(
+ 0,
+ Math.min(
+ Math.round(blur * 1.35),
+ Math.floor(rectWidth / 3),
+ Math.floor(rectHeight / 3)
+ )
+ );
+ const coreWidth = rectWidth - inset * 2;
+ const coreHeight = rectHeight - inset * 2;
+ if (coreWidth <= 0 || coreHeight <= 0) return "";
+ return ``;
})
.join("");
@@ -706,9 +732,9 @@ function buildLocalEditCompositeMaskSvg(params: {
- ${rects}
+ ${softRects}
- ${rects}
+ ${coreRects}
`);
}