diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts index 9a0704f8a..5d9b4f68a 100644 --- a/app/api/canvas/local-edit/route.ts +++ b/app/api/canvas/local-edit/route.ts @@ -1371,7 +1371,7 @@ function buildScaleAdjustZoomedCoordinateSvg(params: { `); } -function buildScaleAdjustFalPhotoGuideSvg(params: { +function buildScaleAdjustMarkedPhotoGuideSvg(params: { width: number; height: number; regions: NormalizedLocalEditRegion[]; @@ -1407,7 +1407,7 @@ function buildScaleAdjustFalPhotoGuideSvg(params: { `); } -async function buildScaleAdjustFalPhotoGuideBuffer(params: { +async function buildScaleAdjustMarkedPhotoGuideBuffer(params: { sourceBuffer: Buffer; width: number; height: number; @@ -1421,7 +1421,7 @@ async function buildScaleAdjustFalPhotoGuideBuffer(params: { .modulate({ brightness: 1.04, saturation: 0.45 }) .composite([ { - input: buildScaleAdjustFalPhotoGuideSvg({ + input: buildScaleAdjustMarkedPhotoGuideSvg({ height, regions, scalePercent, @@ -1572,7 +1572,7 @@ function buildScaleAdjustCoordinatePrompt( scalePercent: ScaleAdjustPercent | null | undefined, sourceSize: { width: number; height: number }, cropReferences: ScaleAdjustCropReference[] = [], - options: { falSafe?: boolean } = {} + options: { falSafe?: boolean; markedPhotoGuide?: boolean } = {} ) { const regionLines = regions .map((region) => { @@ -1653,13 +1653,17 @@ function buildScaleAdjustCoordinatePrompt( ].join("\n"); } + const coordinateGuideLine = options.markedPhotoGuide + ? "输入图片2是一张原图浅化后的完整画面位置参考图,不是输出底图。青色虚线框表示当前主体搜索框(对应下方 OLD),蓝色实线框表示目标最终占位(对应下方 TARGET)。请用输入图片2理解主体在真实室内画面中的位置关系,但最终图不能出现任何框线、色块、标注或参考图的浅化效果。" + : "Input image 2 is a zoomed neutral coordinate instruction map, not a photo and not output content. It enlarges the OLD and TARGET boxes so their relative scale is easy to read; use the numeric pixel coordinates below for the exact absolute position in input image 1. The OLD box/label locates the current furniture; the TARGET box/label gives the required final footprint, center, and scale factor. If the map says OLD OUTSIDE -> BG, rebuild the old full-size furniture area outside TARGET as natural background in the final photo. Read the boxes, labels, arrows, and scale text only as instructions; never output any map graphics."; + return [ "Local furniture scale edit. Use input image 1 as the clean original photo and the locked camera frame.", "One-shot cost constraint: produce the requested edit in this generation without relying on later retries or alternate candidates; an unchanged result is not acceptable.", "中文硬约束:只调整 OLD 框中的主要家具主体。TARGET 框是最终占位;如果是缩小,OLD 框里超出 TARGET 的旧家具占位必须改为自然背景;如果是放大,同一件家具必须明显变大。禁止整图缩放、整图裁切、整图重绘。", "一次成功硬约束:不要保守返回原尺寸。目标家具的可见轮廓必须明显从 OLD 原始占位变到 TARGET 占位;不接受看起来和原图几乎相同的结果。", `Return one seamless realistic photo with the same frame and pixel size as input image 1: ${sourceSize.width} x ${sourceSize.height} px.`, - "Input image 2 is a zoomed neutral coordinate instruction map, not a photo and not output content. It enlarges the OLD and TARGET boxes so their relative scale is easy to read; use the numeric pixel coordinates below for the exact absolute position in input image 1. The OLD box/label locates the current furniture; the TARGET box/label gives the required final footprint, center, and scale factor. If the map says OLD OUTSIDE -> BG, rebuild the old full-size furniture area outside TARGET as natural background in the final photo. Read the boxes, labels, arrows, and scale text only as instructions; never output any map graphics.", + coordinateGuideLine, cropLines ? `${cropLines}` : "", "", "Task:", @@ -1861,10 +1865,11 @@ export async function POST(request: NextRequest) { const useFalScaleAdjustCoordinatePrompt = useScaleAdjustCoordinateGuide && resolvedScaleAdjustModelEntry?.provider?.type === "fal-image"; + const useScaleAdjustMarkedPhotoGuide = useScaleAdjustCoordinateGuide; const annotatedBuffer = isScaleAdjustOperation ? useScaleAdjustCoordinateGuide - ? useFalScaleAdjustCoordinatePrompt - ? await buildScaleAdjustFalPhotoGuideBuffer({ + ? useScaleAdjustMarkedPhotoGuide + ? await buildScaleAdjustMarkedPhotoGuideBuffer({ height: sourceHeight, regions, scalePercent, @@ -1920,7 +1925,10 @@ export async function POST(request: NextRequest) { height: sourceHeight, }, scaleAdjustCropReferences, - { falSafe: useFalScaleAdjustCoordinatePrompt } + { + falSafe: useFalScaleAdjustCoordinatePrompt, + markedPhotoGuide: useScaleAdjustMarkedPhotoGuide, + } ) : buildScaleAdjustPrompt( regions, @@ -1987,8 +1995,8 @@ export async function POST(request: NextRequest) { annotatedReferenceSentToModel: isScaleAdjustOperation, annotatedReferenceType: isScaleAdjustOperation ? useScaleAdjustCoordinateGuide - ? useFalScaleAdjustCoordinatePrompt - ? "scale-adjust-fal-marked-photo-guide" + ? useScaleAdjustMarkedPhotoGuide + ? "scale-adjust-marked-photo-guide" : "scale-adjust-neutral-coordinate-map" : "scale-adjust-full-frame-semantic-edit-map" : "source-overlay", @@ -2008,7 +2016,8 @@ export async function POST(request: NextRequest) { scaleAdjustNeutralCoordinateMapApplied: isScaleAdjustOperation && useScaleAdjustCoordinateGuide && - !useFalScaleAdjustCoordinatePrompt, + !useScaleAdjustMarkedPhotoGuide, + scaleAdjustMarkedPhotoGuideApplied: useScaleAdjustMarkedPhotoGuide, scaleAdjustFalMarkedPhotoGuideApplied: useFalScaleAdjustCoordinatePrompt, scaleAdjustVisualLayoutGuideApplied: isScaleAdjustOperation && !useScaleAdjustCoordinateGuide, @@ -2041,7 +2050,7 @@ export async function POST(request: NextRequest) { ? useScaleAdjustCoordinateGuide ? useFalScaleAdjustCoordinatePrompt ? "fal-safe-marked-photo-box-guide-no-old-crop-v44-one-shot" - : "same-name-zoomed-coordinate-map-no-old-crop-v42-one-shot" + : "same-name-marked-photo-box-guide-no-old-crop-v45-one-shot" : "locked-plate-semantic-target-map-no-old-crop-v15" : undefined, scaleAdjustPostCompositeApplied: false,