From d3cfb4a6b7d7ee8128373fb31728af8fb05c4f7e Mon Sep 17 00:00:00 2001 From: 134 Date: Fri, 3 Jul 2026 17:47:34 +0800 Subject: [PATCH] fix: allow scale adjust target people --- app/api/canvas/local-edit/route.ts | 146 ++++++++++++++--------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts index e51ac90d5..b3f87dbd7 100644 --- a/app/api/canvas/local-edit/route.ts +++ b/app/api/canvas/local-edit/route.ts @@ -2567,38 +2567,38 @@ function buildScaleAdjustCoordinatePrompt( const isEnlarge = widthFactor > 1.08 || heightFactor > 1.08; const scaleDirection = isShrink - ? "make the furniture clearly smaller" + ? "make the selected subject clearly smaller" : isEnlarge - ? "make the furniture clearly larger" - : "move/fit the furniture to the target box"; + ? "make the selected subject clearly larger" + : "move/fit the selected subject to the target box"; const footprintRule = isShrink - ? "After shrinking, the original OLD footprint outside the TARGET box must be cleared and rebuilt as natural background/floor/rug/wall; the furniture must not still touch the OLD box edges." + ? "After shrinking, the original OLD footprint outside the TARGET box must be cleared and rebuilt as natural background/floor/rug/wall; the selected subject must not still touch the OLD box edges." : isEnlarge - ? "After enlarging, the same furniture should visibly occupy more of the TARGET footprint, with natural shadows and occlusion; do not just move it or stretch one axis." + ? "After enlarging, the same selected subject should visibly occupy more of the TARGET footprint, with natural shadows and occlusion; do not just move it or stretch one axis." : "Keep the subject centered on the TARGET box without changing the full canvas."; const cropNote = cropIndex >= 0 ? options.falSafe ? ` Input image ${cropIndex + 3} is an extra identity and silhouette reference.` - : ` Input image ${cropIndex + 3} is a clean crop reference for this same furniture identity and silhouette; use it only to recognize the subject, never paste it, and do not preserve its old size.` + : ` Input image ${cropIndex + 3} is a clean crop reference for this same target subject identity and silhouette; use it only to recognize the subject, never paste it, and do not preserve its old size.` : ""; if (options.falSafe) { const actionPhrase = isShrink - ? "resize the furniture proportionally smaller and place it inside the final footprint" + ? "resize the selected subject proportionally smaller and place it inside the final footprint" : isEnlarge - ? "resize the same furniture proportionally larger toward the final footprint" - : "place the same furniture subject on the final footprint"; + ? "resize the same selected subject proportionally larger toward the final footprint" + : "place the same selected subject on the final footprint"; const blendPhrase = isShrink ? "Blend the newly visible floor, rug, wall, window area, shadow, and background around it naturally." : isEnlarge ? "Blend edges, contact shadows, and occlusion with the surrounding room naturally." : "Keep the surrounding room stable."; - return `Region ${region.index}: current furniture box in source photo left=${region.pixelRect.left}, top=${region.pixelRect.top}, right=${sourceRight}, bottom=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; requested final footprint left=${targetPixelRect.left}, top=${targetPixelRect.top}, right=${targetRight}, bottom=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; scale factor width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. Edit direction: ${actionPhrase}. ${blendPhrase}${cropNote}`; + return `Region ${region.index}: current target-subject search box in source photo left=${region.pixelRect.left}, top=${region.pixelRect.top}, right=${sourceRight}, bottom=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; requested final footprint left=${targetPixelRect.left}, top=${targetPixelRect.top}, right=${targetRight}, bottom=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; scale factor width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. Edit direction: ${actionPhrase}. ${blendPhrase}${cropNote}`; } - return `Region ${region.index}: OLD search box in input 1 left=${region.pixelRect.left}, top=${region.pixelRect.top}, right=${sourceRight}, bottom=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; TARGET final visual footprint left=${targetPixelRect.left}, top=${targetPixelRect.top}, right=${targetRight}, bottom=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; target scale is ${widthFactor.toFixed(2)}x width and ${heightFactor.toFixed(2)}x height. Main action: ${scaleDirection}.${userInstructionLine} The final furniture silhouette must clearly leave the OLD footprint edges and align much closer to TARGET than OLD; returning an almost unchanged furniture footprint is not acceptable. ${footprintRule}${cropNote}`; + return `Region ${region.index}: OLD search box in input 1 left=${region.pixelRect.left}, top=${region.pixelRect.top}, right=${sourceRight}, bottom=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; TARGET final visual footprint left=${targetPixelRect.left}, top=${targetPixelRect.top}, right=${targetRight}, bottom=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; target scale is ${widthFactor.toFixed(2)}x width and ${heightFactor.toFixed(2)}x height. Main action: ${scaleDirection}.${userInstructionLine} The final selected-subject silhouette must clearly leave the OLD footprint edges and align much closer to TARGET than OLD; returning an almost unchanged target subject footprint is not acceptable. ${footprintRule}${cropNote}`; }) .join("\n"); const cropLines = cropReferences @@ -2610,13 +2610,13 @@ function buildScaleAdjustCoordinatePrompt( if (options.falSafe) { return [ - "Interior furniture photo edit.", + "Interior selected-subject scale photo edit.", `Return one realistic photo with the same camera frame and pixel size as input image 1: ${sourceSize.width} x ${sourceSize.height} px.`, "Input image 1 is the source photo. Input image 2 is a marked copy of the source photo for location guidance only and should not appear in the final photo.", - "In the guide, the cyan dashed box marks the existing furniture area and the blue solid box marks the requested final footprint.", - "Resize only the furniture subject indicated by each current box. Keep the camera, room layout, walls, windows, floor, rug, sofa, lamp, text, and background stable.", - "Preserve the furniture identity, material, perspective, objects on top, and natural aspect ratio.", - "For a smaller final footprint, show the furniture smaller and blend newly visible floor, rug, wall, window area, shadow, and background around it naturally. For a larger final footprint, scale the same furniture proportionally with natural edges and contact shadows.", + "In the guide, the cyan dashed box marks the existing selected target subject area and the blue solid box marks the requested final footprint.", + "Resize only the selected target subject indicated by each current box. The target may be a person/model/child/body part, furniture, product, or another object. Keep the camera, room layout, walls, windows, floor, rug, sofa, lamp, text, background, and all non-target subjects stable.", + "Preserve the target identity, person anatomy/face/clothing or product material/structure, perspective, contact shadows, and natural aspect ratio/proportions.", + "For a smaller final footprint, show the selected subject smaller and blend newly visible floor, rug, wall, window area, shadow, and background around it naturally. For a larger final footprint, scale the same selected subject proportionally with natural edges and contact shadows.", "Return a clean photo without guide marks, boxes, arrows, overlays, patch edges, color mismatch, or full-frame zoom.", cropLines ? `${cropLines}` : "", "", @@ -2629,31 +2629,31 @@ function buildScaleAdjustCoordinatePrompt( ? "输入图片2是一张完整画面的粗略目标布局草稿,不是输出底图。它把 OLD 源框旧主体占位洗淡,表示旧尺寸主体必须从原尺寸位置移除并自然修复背景;同时把目标主体粗略缩放/移动到 TARGET 最终占位附近,这个缩小后的位置和尺寸是最终结果必须匹配的几何目标。请把 input 2 当成最终构图/比例的强约束:如果 input 2 中目标主体比 input 1 小,最终输出也必须明显变小,不能保留 input 1 的原尺寸主体。不要复制 input 2 的淡化痕迹、粗糙拼接、局部透明边、矩形补丁、亮度变化或参考图画质;最终必须以 input 1 的真实照片为唯一画面基底重新完成无缝图片编辑。" : 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."; + : "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 selected subject; 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 subject 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.", + "Local selected-subject 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 占位;不接受看起来和原图几乎相同的结果。", + "中文硬约束:只调整 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.`, coordinateGuideLine, cropLines ? `${cropLines}` : "", "", "Task:", - "Find the main movable furniture subject inside each OLD box in input image 1. Resize and, if needed, move that subject only so its final visible footprint matches the TARGET box shown in input image 2 and the numeric TARGET coordinates below.", - "Do a real subject-scale edit, not a full image zoom. The camera, room layout, windows, wall decor, text, floor, rug, and all non-target furniture must remain stable.", - "If an OLD box contains more than one object, choose the dominant furniture/product inside that box, usually the largest or most central movable item. Keep adjacent lamps, plants, side tables, pillows, wall decor, windows, text, and background objects at their original size unless they are clearly part of the same furniture subject.", - "Keep the furniture identity, material, perspective, objects on top, and natural aspect ratio from input image 1. Do not create a second copy or extra parts. Do not preserve the original furniture size just because the scene looks realistic; the user explicitly wants a visible scale change.", - "For beds, sofas, tables, chairs, cabinets, benches, and other large furniture, still perform the scale edit on that furniture. Do not treat large furniture as locked architecture.", - "If the target is smaller, the furniture must visibly become smaller and be mostly contained by the TARGET footprint. Rebuild the OLD area outside the TARGET footprint as newly exposed floor, rug, wall, bedding, shadows, and background. If the target is larger, enlarge the same furniture naturally without stretching it.", - "缩小时请优先让目标家具明显缩小,而不是为了保守而保持原样。不接受原尺寸保留、只轻微变形、或只改变整张图构图。", - "Do not keep the selected furniture at its original footprint. The edited furniture should fit the TARGET rectangle much better than the OLD rectangle.", + "Find the main selected target subject inside each OLD box in input image 1. The target can be a person/model/child/body part, furniture, product, or another movable object. Resize and, if needed, move that subject only so its final visible footprint matches the TARGET box shown in input image 2 and the numeric TARGET coordinates below.", + "Do a real subject-scale edit, not a full image zoom. The camera, room layout, windows, wall decor, text, floor, rug, and all non-target subjects must remain stable.", + "If an OLD box contains more than one object/person, choose the dominant target subject inside that box, usually the largest or most central selected item/person. Keep adjacent lamps, plants, side tables, pillows, wall decor, windows, text, background objects, and non-target people at their original size unless they are clearly part of the same target subject.", + "Keep the target identity, person face/anatomy/clothing or product material/structure, perspective, contact shadows, and natural aspect ratio/proportions from input image 1. Do not create a second copy or extra parts. Do not preserve the original target size just because the scene looks realistic; the user explicitly wants a visible scale change.", + "For beds, sofas, tables, chairs, cabinets, benches, people, models, children, hands, and other large visible subjects, still perform the scale edit on that selected subject. Do not treat the selected subject as locked background.", + "If the target is smaller, the selected subject must visibly become smaller and be mostly contained by the TARGET footprint. Rebuild the OLD area outside the TARGET footprint as newly exposed floor, rug, wall, bedding, shadows, or background. If the target is larger, enlarge the same selected subject naturally without stretching it.", + "缩小时请优先让目标主体明显缩小,而不是为了保守而保持原样。不接受原尺寸保留、只轻微变形、或只改变整张图构图。", + "Do not keep the selected subject at its original footprint. The edited subject should fit the TARGET rectangle much better than the OLD rectangle.", "", "Region requirements:", regionLines, "", - "Success check: compare the final furniture footprint with input image 1 and the neutral coordinate map in input image 2. The selected furniture size must clearly change from the original and align much closer to TARGET than OLD, while the rest of the photo stays stable.", + "Success check: compare the final selected-subject footprint with input image 1 and the neutral coordinate map in input image 2. The selected subject size must clearly change from the original and align much closer to TARGET than OLD, while the rest of the photo stays stable.", "Do not paste rectangular image areas. Do not output coordinate-map lines, labels, boxes, arrows, scale text, muted wash, overlays, seams, hard patch edges, haze, color mismatch, full-canvas zoom, crop, pan, or redesign.", "Return only the clean edited photo.", ].join("\n"); @@ -2661,12 +2661,12 @@ function buildScaleAdjustCoordinatePrompt( function buildScaleAdjustCoordinateSystemPrompt() { return [ - "You are an image editing model for local furniture scale adjustment.", + "You are an image editing model for local selected-subject scale adjustment.", "Input image 1 is the only final photo base. Input image 2 is a zoomed neutral coordinate instruction map, not a photo layer.", - "Follow both English and Chinese instructions. The Chinese lines are hard constraints for avoiding unchanged furniture and full-canvas zoom.", - "Generate a clean realistic final photo by editing the target furniture itself and naturally rebuilding only the tiny surrounding background that becomes visible.", - "Prefer a clear visible size change over a conservative unchanged result; unchanged furniture is not acceptable.", - "When shrinking, rebuild the old full-size furniture footprint outside the target footprint as natural background. Large furniture is editable and must not remain locked at original size.", + "Follow both English and Chinese instructions. The Chinese lines are hard constraints for avoiding an unchanged selected target subject and full-canvas zoom.", + "Generate a clean realistic final photo by editing the selected target subject itself and naturally rebuilding only the tiny surrounding background that becomes visible.", + "The target subject can be a person/model/child/body part, furniture, product, or another movable object. Prefer a clear visible size change over a conservative unchanged result; an unchanged target subject is not acceptable.", + "When shrinking, rebuild the old full-size target-subject footprint outside the target footprint as natural background. Large selected subjects are editable and must not remain locked at original size.", "Do not paste, composite, clone, crop, resize, or copy rectangular image patches from any input.", "Never output guide artifacts from the edit map: no faded wash, placeholder shadow, overlay patch, rough crop rectangle, lines, labels, blocks, seams, rectangular borders, arrows, masks, UI marks, or annotations.", "Keep the camera frame, lighting, wall, floor, rug, windows, background furniture, text, logos, and all non-target regions stable.", @@ -2682,7 +2682,7 @@ function buildScaleAdjustTextOnlyPrompt( const cropLines = cropReferences .map( (reference, index) => - `Input image ${index + 2}: clean crop reference for Region ${reference.regionIndex}; use it only to identify the furniture subject and its natural aspect ratio, never paste the crop into the output.` + `Input image ${index + 2}: clean crop reference for Region ${reference.regionIndex}; use it only to identify the selected target subject and its natural aspect ratio/proportions, never paste the crop into the output.` ) .join("\n"); const regionLines = regions @@ -2704,27 +2704,27 @@ function buildScaleAdjustTextOnlyPrompt( const targetBottom = targetPixelRect.top + targetPixelRect.height; const cropNote = cropIndex >= 0 - ? ` Input image ${cropIndex + 2} is the clean crop reference for this furniture identity and silhouette.` + ? ` Input image ${cropIndex + 2} is the clean crop reference for this target-subject identity and silhouette.` : ""; - return `Region ${region.index}: hidden coordinate set A current area x0=${region.pixelRect.left}, y0=${region.pixelRect.top}, x1=${sourceRight}, y1=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; hidden coordinate set B final size/location x0=${targetPixelRect.left}, y0=${targetPixelRect.top}, x1=${targetRight}, y1=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; final visual scale width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. User request: ${region.prompt || "make the same furniture match set B"}.${cropNote}`; + return `Region ${region.index}: hidden coordinate set A current area x0=${region.pixelRect.left}, y0=${region.pixelRect.top}, x1=${sourceRight}, y1=${sourceBottom}, width=${region.pixelRect.width}, height=${region.pixelRect.height}; hidden coordinate set B final size/location x0=${targetPixelRect.left}, y0=${targetPixelRect.top}, x1=${targetRight}, y1=${targetBottom}, width=${targetPixelRect.width}, height=${targetPixelRect.height}; final visual scale width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. User request: ${region.prompt || "make the same selected target subject match set B"}.${cropNote}`; }) .join("\n"); return [ - "Local furniture scale edit. Input image 1 is the locked source photo and the only final canvas base.", + "Local selected-subject scale edit. Input image 1 is the locked source photo and the only final canvas base.", `Return one clean realistic photo with exactly the same camera frame and pixel size as input image 1: ${sourceSize.width} x ${sourceSize.height} px.`, cropLines ? cropLines : "", "The final photo must contain only natural scene content. Never add artificial graphic overlays, visible coordinate aids, labels, lines, UI elements, or text.", - "Only edit the main movable furniture subject inside each current pixel area. Keep all other furniture, sofa, lamps, wall, windows, rug, floor, decor, lighting, and camera frame stable.", + "Only edit the main selected target subject inside each current pixel area. The target can be a person/model/child/body part, furniture, product, or another object. Keep all other non-target subjects, furniture, sofa, lamps, wall, windows, rug, floor, decor, lighting, and camera frame stable.", "Use the numeric pixel sets below as hidden instructions only; they are not visual content and must not be drawn.", - "When set B is smaller than set A, make the same furniture visibly smaller and naturally rebuild the newly visible floor, rug, wall, shadow, or background around it. Do not leave the old full-size furniture silhouette.", - "Keep the furniture identity, materials, perspective, objects on top, contact shadows, and natural aspect ratio. Do not stretch, squash, duplicate, or paste a rectangular crop.", - "中文硬约束:输入图1是锁定底图,只能调整 A 像素范围里的主要家具主体,让它变成 B 像素范围对应的大小和位置。A/B 坐标只是隐藏指令,最终照片里绝对不能画出任何线条、框、文字、标注或 UI 元素。", + "When set B is smaller than set A, make the same selected target subject visibly smaller and naturally rebuild the newly visible floor, rug, wall, shadow, or background around it. Do not leave the old full-size subject silhouette.", + "Keep the target identity, person anatomy/face/clothing or product material/structure, perspective, contact shadows, and natural aspect ratio/proportions. Do not stretch, squash, duplicate, or paste a rectangular crop.", + "中文硬约束:输入图1是锁定底图,只能调整 A 像素范围里的主要目标主体,目标可以是人物、模特、小孩、手臂身体、商品或家具,让它变成 B 像素范围对应的大小和位置。A/B 坐标只是隐藏指令,最终照片里绝对不能画出任何线条、框、文字、标注或 UI 元素。", "", "Region instructions:", regionLines, "", - "Success check before returning: the selected furniture must be clearly closer to set B than to set A, while the rest of the photo remains visually unchanged and clean.", + "Success check before returning: the selected target subject must be clearly closer to set B than to set A, while the rest of the photo remains visually unchanged and clean.", ].filter(Boolean).join("\n"); } @@ -2771,21 +2771,21 @@ function buildScaleAdjustPatchPrompt( const firstInputRole = targetDraftPrimary ? structureLockedDraft ? includeSourceReference - ? "Input image 1 is a rough product-structure-locked target crop. The selected furniture/product was moved and scaled using source-photo pixels, so its final size, position, rods, panels, weave, wheels, material, and perspective are the hard target. Repair rough background holes, edge halos, blur, occlusion, contact shadows, and surface artifacts without redesigning the product. Input image 2 is only the clean background/person reference, never the size reference." - : "Input image 1 is a rough product-structure-locked target crop and the only visual reference. The selected furniture/product was moved and scaled using source-photo pixels, so its final size, position, rods, panels, weave, wheels, material, and perspective are the hard target. Repair rough background holes, edge halos, blur, occlusion, contact shadows, and surface artifacts without redesigning the product." + ? "Input image 1 is a rough subject-structure-locked target crop. The selected target subject was moved and scaled using source-photo pixels, so its final size, position, silhouette, material/skin/clothing, perspective, and visible structure are the hard target. If the subject is a person, keep the same person identity, face, body proportions, pose, hair, hands, and clothing while cleaning rough edges. If the subject is furniture/product, keep rods, panels, weave, wheels, material, and product structure. Repair rough background holes, edge halos, blur, occlusion, contact shadows, and surface artifacts without redesigning the subject. Input image 2 is only the clean background and non-target reference, never the old size reference." + : "Input image 1 is a rough subject-structure-locked target crop and the only visual reference. The selected target subject was moved and scaled using source-photo pixels, so its final size, position, silhouette, material/skin/clothing, perspective, and visible structure are the hard target. If the subject is a person, keep the same person identity, face, body proportions, pose, hair, hands, and clothing while cleaning rough edges. If the subject is furniture/product, keep rods, panels, weave, wheels, material, and product structure. Repair rough background holes, edge halos, blur, occlusion, contact shadows, and surface artifacts without redesigning the subject." : includeSourceReference - ? "Input image 1 is the rough edited target-layout crop. It is the hard layout target: the selected furniture size and center in the final output must match this draft, but the rough wash, ghosted old footprint, placeholder shadow, blur, and patch artifacts must be cleaned." - : "Input image 1 is the rough edited target-layout crop and the only visual reference. It is the hard layout target: the selected furniture size and center in the final output must match this draft. Clean away the rough wash, ghosted old footprint, placeholder shadow, blur, and patch artifacts." + ? "Input image 1 is the rough edited target-layout crop. It is the hard layout target: the selected subject size and center in the final output must match this draft, but the rough wash, ghosted old footprint, placeholder shadow, blur, and patch artifacts must be cleaned." + : "Input image 1 is the rough edited target-layout crop and the only visual reference. It is the hard layout target: the selected subject size and center in the final output must match this draft. Clean away the rough wash, ghosted old footprint, placeholder shadow, blur, and patch artifacts." : "Input image 1 is the exact crop from the original photo and is the locked crop base."; const secondInputRole = targetDraftPrimary ? includeSourceReference - ? "Input image 2 is the original clean crop. Use it for stable crop framing, background texture, lighting, perspective, furniture identity, and non-target human/person preservation. Do not restore the selected furniture to its old size from this image." + ? "Input image 2 is the original clean crop. Use it for stable crop framing, background texture, lighting, perspective, target identity, and non-target person/object preservation. Do not restore the selected subject to its old size from this image." : "" - : "Input image 2 is a rough target-layout draft of the same crop. It is the hard layout target for the selected furniture size and position. Use it to understand the final footprint and newly visible background area, then remove any rough seams, washed areas, placeholder shadows, blur, or patch artifacts from that draft."; + : "Input image 2 is a rough target-layout draft of the same crop. It is the hard layout target for the selected subject size and position. Use it to understand the final footprint and newly visible background area, then remove any rough seams, washed areas, placeholder shadows, blur, or patch artifacts from that draft."; const cropLines = cropReferences .map( (reference, index) => - `Input image ${index + cropReferenceStartIndex}: clean identity crop for Region ${reference.regionIndex}; use it only to recognize the target furniture shape and materials, not its old size.` + `Input image ${index + cropReferenceStartIndex}: clean identity crop for Region ${reference.regionIndex}; use it only to recognize the target subject shape, identity, anatomy/materials, and natural aspect ratio, not its old size.` ) .join("\n"); const regionLines = regions @@ -2811,15 +2811,15 @@ function buildScaleAdjustPatchPrompt( region.rect.height > 0 ? targetRect.height / region.rect.height : 1; const action = widthFactor < 0.92 || heightFactor < 0.92 - ? "make the same furniture visibly smaller" + ? "make the same selected subject visibly smaller" : widthFactor > 1.08 || heightFactor > 1.08 - ? "make the same furniture visibly larger" - : "move the same furniture to the final footprint"; + ? "make the same selected subject visibly larger" + : "move the same selected subject to the final footprint"; const cropNote = cropIndex >= 0 - ? ` Input image ${cropIndex + cropReferenceStartIndex} is the clean identity reference for this exact furniture.` + ? ` Input image ${cropIndex + cropReferenceStartIndex} is the clean identity reference for this exact target subject.` : ""; - return `Region ${region.index}: current search area inside input image ${sourceInputIndex} crop is x=${sourceInPatch.left}, y=${sourceInPatch.top}, w=${sourceInPatch.width}, h=${sourceInPatch.height}; final visual footprint inside input image ${draftInputIndex} / output crop is x=${targetInPatch.left}, y=${targetInPatch.top}, w=${targetInPatch.width}, h=${targetInPatch.height}; requested scale width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. User request: ${region.prompt || action}. Main action: ${action}. The final object must be much closer to the final footprint than to the current search area.${cropNote}`; + return `Region ${region.index}: current search area inside input image ${sourceInputIndex} crop is x=${sourceInPatch.left}, y=${sourceInPatch.top}, w=${sourceInPatch.width}, h=${sourceInPatch.height}; final visual footprint inside input image ${draftInputIndex} / output crop is x=${targetInPatch.left}, y=${targetInPatch.top}, w=${targetInPatch.width}, h=${targetInPatch.height}; requested scale width=${widthFactor.toFixed(2)}, height=${heightFactor.toFixed(2)}. User request: ${region.prompt || action}. Main action: ${action}. Treat the main selected subject inside the search area as the target; it may be a person, model, child, body part, furniture, product, or other object. The final subject must be much closer to the final footprint than to the current search area.${cropNote}`; }) .join("\n"); const chineseHardConstraint = (() => { @@ -2828,30 +2828,30 @@ function buildScaleAdjustPatchPrompt( } if (structureLockedDraft) { return includeSourceReference - ? "中文硬约束:输入图1已经用原图产品像素把目标家具/产品放到目标尺寸和目标位置,产品结构、杆件、面板、编织纹理、轮子、材质和透视都要按输入图1保留。输入图2只能作为干净背景、人物、光影参考,绝对不能把产品恢复成输入图2里的旧尺寸。不能重新设计或替换产品,但要清理产品表面的草稿黑斑、破洞、脏点、灰块和藤编断裂,让藤编面板连续干净、轮子只出现在底部。" - : "中文硬约束:输入图1已经用原图产品像素把目标家具/产品放到目标尺寸和目标位置,产品结构、杆件、面板、编织纹理、轮子、材质和透视都要按输入图1保留。不能重新设计或替换产品,但要清理产品表面的草稿黑斑、破洞、脏点、灰块和藤编断裂,让藤编面板连续干净、轮子只出现在底部。"; + ? "中文硬约束:输入图1已经用原图像素把目标主体放到目标尺寸和目标位置,目标主体可以是人物、模特、小孩、手臂身体、商品或家具。人物目标必须按输入图1保留同一身份、脸部、身体比例、姿态、发型、手部和服装;商品/家具目标必须保留产品结构、杆件、面板、编织纹理、轮子、材质和透视。输入图2只能作为干净背景、光影和非目标元素参考,绝对不能把目标主体恢复成输入图2里的旧尺寸。不能重新设计或替换目标主体,只清理草稿边缘、黑斑、破洞、脏点、灰块、皮肤/服装/产品表面伪影。" + : "中文硬约束:输入图1已经用原图像素把目标主体放到目标尺寸和目标位置,目标主体可以是人物、模特、小孩、手臂身体、商品或家具。人物目标必须按输入图1保留同一身份、脸部、身体比例、姿态、发型、手部和服装;商品/家具目标必须保留产品结构、杆件、面板、编织纹理、轮子、材质和透视。不能重新设计或替换目标主体,只清理草稿边缘、黑斑、破洞、脏点、灰块、皮肤/服装/产品表面伪影。"; } return includeSourceReference - ? "中文硬约束:输入图1是目标大小/位置草稿,必须按它的目标尺寸和目标位置输出;输入图2只是原始质感、人物和背景参考,绝对不要把家具恢复成输入图2里的旧尺寸。只输出同一裁切范围的干净局部照片,去掉草稿中的泛白、残影和拼接感。" - : "中文硬约束:输入图1是唯一视觉参考和目标大小/位置草稿,必须按它的目标尺寸和目标位置输出。不要找回旧尺寸家具。只输出同一裁切范围的干净局部照片,去掉草稿中的泛白、残影和拼接感。"; + ? "中文硬约束:输入图1是目标大小/位置草稿,必须按它的目标尺寸和目标位置输出;输入图2只是原始质感、非目标人物和背景参考,绝对不要把目标主体恢复成输入图2里的旧尺寸。只输出同一裁切范围的干净局部照片,去掉草稿中的泛白、残影和拼接感。" + : "中文硬约束:输入图1是唯一视觉参考和目标大小/位置草稿,必须按它的目标尺寸和目标位置输出。不要找回旧尺寸目标主体。只输出同一裁切范围的干净局部照片,去掉草稿中的泛白、残影和拼接感。"; })(); return [ - "Local furniture scale edit inside a cropped workspace.", + "Local selected-subject scale edit inside a cropped workspace.", `Return exactly one clean realistic crop with the same framing and aspect as input image 1. The crop represents full-photo pixels left=${patchReference.workspacePixelRect.left}, top=${patchReference.workspacePixelRect.top}, width=${patchReference.workspacePixelRect.width}, height=${patchReference.workspacePixelRect.height}.`, firstInputRole, secondInputRole, cropLines, - "Only edit the selected movable furniture subject. Keep the crop borders, wall, window frame, floor, rug, sofa, lamps, decor, lighting, camera perspective, and all non-target furniture stable.", - "If people, faces, arms, hands, bodies, hair, or worn clothing appear in the crop, they are not furniture. Preserve the human scale, identity, pose, face, hand shape, and clothing position as much as possible; do not enlarge, shrink, duplicate, or redraw the person as part of the furniture scale edit.", - "When the final footprint is smaller, the selected furniture must clearly shrink; erase the old larger furniture footprint outside the final footprint and replace it with natural background/floor/rug/wall/shadow that matches the original crop.", + "Only edit the selected target subject inside the search area. The target subject can be a person/model/child/body part, furniture, product, or another movable object. Keep the crop borders, wall, window frame, floor, rug, sofa, lamps, decor, lighting, camera perspective, and all non-target subjects stable.", + "If the selected target is a person, scale the whole visible person/body coherently to the final footprint while preserving identity, face, pose, anatomy, hand shape, hair, clothing, and natural human proportions. If a person appears outside the selected target, preserve that non-target person without resizing or redrawing them.", + "When the final footprint is smaller, the selected subject must clearly shrink; erase the old larger subject footprint outside the final footprint and replace it with natural background/floor/rug/wall/shadow that matches the original crop.", structureLockedDraft - ? "When the final footprint is larger, the target draft already places the same furniture/product at the required larger size. Do not redesign the product geometry; keep the locked rods, panels, weave, wheels, material, and perspective while cleaning background gaps, boundary blending, rough surface artifacts, natural occlusion, and contact shadows." - : "When the final footprint is larger, enlarge the selected furniture itself to match the target draft while keeping nearby people and hands natural. If a hand touches or holds an item on the furniture, keep the hand anatomically plausible and use the original crop as the person-preservation reference.", - "Keep the same furniture identity, material, perspective, object details, contact shadows, and natural aspect ratio. Do not stretch, squash, duplicate, or replace it with a different item.", - "Hard failure condition: if the selected furniture remains near its original old size, the answer is wrong. The output must visibly change the furniture footprint to match the target draft footprint.", + ? "When the final footprint is larger, the target draft already places the same selected subject at the required larger size. Do not redesign the subject geometry/anatomy; keep the locked person identity/anatomy/clothing or product structure/material/perspective while cleaning background gaps, boundary blending, rough surface artifacts, natural occlusion, and contact shadows." + : "When the final footprint is larger, enlarge the selected subject itself to match the target draft while keeping nearby non-target people and hands natural. If the target is a person, preserve anatomy and identity instead of inventing a new person.", + "Keep the same target identity, perspective, visible details, contact shadows, and natural aspect ratio/proportions. Do not stretch, squash, duplicate, or replace it with a different subject.", + "Hard failure condition: if the selected target subject remains near its original old size, the answer is wrong. The output must visibly change the selected subject footprint to match the target draft footprint.", structureLockedDraft - ? "Remove every rough draft artifact from input image 1: gray fill patches, beige wash, flat painted areas, jagged mask holes, broken woven-panel cells, black speckled stains, dark blotches on cane panels, rectangular crop edges, and ghost fragments. Woven panels must look like continuous clean cane weave; wheels belong only under the bottom frame, not as black stains inside the woven panel. Rods, wheels, and hooks must remain the same product structure, with natural material texture." + ? "Remove every rough draft artifact from input image 1: gray fill patches, beige wash, flat painted areas, jagged mask holes, black speckled stains, dark blotches, rectangular crop edges, and ghost fragments. Human skin, face, hands, hair, and clothing must look continuous and natural when the target is a person. Woven panels, wheels, rods, hooks, and product surfaces must remain continuous and clean when the target is furniture/product." : "", "Do not output boxes, lines, labels, coordinate marks, UI marks, text, arrows, overlays, rough layout artifacts, rectangular patch edges, or a full-room image.", chineseHardConstraint, @@ -2859,7 +2859,7 @@ function buildScaleAdjustPatchPrompt( "Region instructions:", regionLines, "", - "Success check before returning: the selected furniture footprint must be clearly closer to the final footprint than the current search area, and the crop must look like one natural photograph.", + "Success check before returning: the selected target subject footprint must be clearly closer to the final footprint than the current search area, and the crop must look like one natural photograph.", ].filter(Boolean).join("\n"); } @@ -3198,12 +3198,12 @@ export async function POST(request: NextRequest) { ) : buildLocalEditPrompt(regions); const scaleAdjustCoordinateNegativePrompt = useFalScaleAdjustCoordinatePrompt - ? "guide marks, labels, boxes, arrows, overlays, patch edges, color mismatch, full-frame zoom, duplicate furniture, stretched furniture, distorted furniture" - : "visible annotation, guide overlay, translucent overlay, target placement overlay, faded wash, placeholder shadow, text label, arrows, boxes, rectangle border, UI marks, pasted patch, rough layout patch, hard crop edge, seam, hard rectangular edge, color mismatch, different-resolution area, whole image zoom, whole image crop, whole image pan, whole image redesign, unchanged target furniture, old-size target furniture, stretched furniture, squashed furniture, duplicate furniture, second copy, extra legs, extra rails, side panels, shelves, cabinets, lattice panels"; + ? "guide marks, labels, boxes, arrows, overlays, patch edges, color mismatch, full-frame zoom, unchanged target subject, duplicate subject, duplicate furniture, duplicate person, stretched furniture, distorted furniture, deformed person, changed face, extra limbs" + : "visible annotation, guide overlay, translucent overlay, target placement overlay, faded wash, placeholder shadow, text label, arrows, boxes, rectangle border, UI marks, pasted patch, rough layout patch, hard crop edge, seam, hard rectangular edge, color mismatch, different-resolution area, whole image zoom, whole image crop, whole image pan, whole image redesign, unchanged target subject, old-size target subject, unchanged target person, old-size target person, unchanged target furniture, old-size target furniture, stretched subject, squashed subject, distorted subject, stretched furniture, squashed furniture, duplicate subject, duplicate person, duplicate furniture, second copy, changed face, deformed person, broken anatomy, extra limbs, extra fingers, extra legs, extra rails, side panels, shelves, cabinets, lattice panels"; const scaleAdjustTextOnlyNegativePrompt = - "artificial graphic overlay, visible coordinate aid, visible line, visible label, UI element, annotation text, full image redesign, full-frame zoom, crop, pan, pasted crop, hard patch edge, color mismatch, changed sofa, changed lamp, changed wall, changed rug, duplicate furniture, stretched furniture, distorted furniture"; + "artificial graphic overlay, visible coordinate aid, visible line, visible label, UI element, annotation text, full image redesign, full-frame zoom, crop, pan, pasted crop, hard patch edge, color mismatch, changed sofa, changed lamp, changed wall, changed rug, duplicate subject, duplicate person, duplicate furniture, changed face, deformed person, extra limbs, stretched subject, stretched furniture, distorted furniture"; const scaleAdjustPatchNegativePrompt = - "full room image, changed crop border, artificial graphic overlay, visible coordinate aid, visible line, visible label, UI element, annotation text, guide mark, pasted crop, hard patch edge, color mismatch, gray draft patch, beige wash patch, flat painted area, broken woven panel, jagged mask hole, black speckled stain, dark blotch on cane panel, dirty woven panel, wheel inside woven panel, duplicate furniture, unchanged target furniture, changed locked product, redrawn product interior, different furniture, stretched furniture, distorted furniture"; + "full room image, changed crop border, artificial graphic overlay, visible coordinate aid, visible line, visible label, UI element, annotation text, guide mark, pasted crop, hard patch edge, color mismatch, gray draft patch, beige wash patch, flat painted area, jagged mask hole, black speckled stain, dark blotch, duplicate subject, duplicate person, duplicate furniture, unchanged target subject, unchanged target person, unchanged target furniture, old-size target subject, changed target identity, changed face, deformed person, broken anatomy, extra limbs, extra fingers, changed locked product, redrawn product interior, different furniture, broken woven panel, dirty woven panel, wheel inside woven panel, stretched subject, stretched furniture, distorted furniture"; const manualRegionReferenceImageUrls = regions.flatMap((region) => region.referenceImages.map((reference) => reference.url) );