Fix canvas scale adjust local edit build
This commit is contained in:
parent
accaaad8f1
commit
c9ed662809
@ -199,6 +199,32 @@ function inferClosestAspectRatio(width: number, height: number) {
|
||||
return closest;
|
||||
}
|
||||
|
||||
function inferScaleAdjustPatchAspectRatio(width: number, height: number) {
|
||||
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
|
||||
return "1:1";
|
||||
}
|
||||
const sourceRatio = width / height;
|
||||
const providerSafeRatios = [
|
||||
"1:1",
|
||||
"2:3",
|
||||
"3:2",
|
||||
"3:4",
|
||||
"4:3",
|
||||
"9:16",
|
||||
"16:9",
|
||||
] as const;
|
||||
let closest: (typeof providerSafeRatios)[number] = "1:1";
|
||||
let closestDiff = Number.POSITIVE_INFINITY;
|
||||
for (const candidate of providerSafeRatios) {
|
||||
const diff = Math.abs(parseAspectRatioValue(candidate) - sourceRatio);
|
||||
if (diff < closestDiff) {
|
||||
closest = candidate;
|
||||
closestDiff = diff;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
function resolveLocalEditAspectRatio(input: unknown, sourceWidth: number, sourceHeight: number) {
|
||||
const requested = String(input || "").trim();
|
||||
if (
|
||||
@ -339,7 +365,26 @@ function isScaleAdjustFalNanoBananaEditModel(
|
||||
const label = `${entry.model.displayName || ""} ${entry.model.modelId || ""}`
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, " ");
|
||||
return label.includes("/edit") || /\bedit\b/.test(label);
|
||||
const capabilities =
|
||||
entry.model.capabilities && typeof entry.model.capabilities === "object"
|
||||
? (entry.model.capabilities as Record<string, unknown>)
|
||||
: {};
|
||||
const defaultParams =
|
||||
entry.model.defaultParams && typeof entry.model.defaultParams === "object"
|
||||
? (entry.model.defaultParams as Record<string, unknown>)
|
||||
: {};
|
||||
const editEndpoint =
|
||||
typeof capabilities.editEndpoint === "string"
|
||||
? capabilities.editEndpoint
|
||||
: typeof defaultParams.editEndpoint === "string"
|
||||
? defaultParams.editEndpoint
|
||||
: "";
|
||||
return (
|
||||
label.includes("/edit") ||
|
||||
/\bedit\b/.test(label) ||
|
||||
capabilities.autoRouteEditEndpoint === true ||
|
||||
editEndpoint.toLowerCase().includes("/edit")
|
||||
);
|
||||
}
|
||||
|
||||
function isScaleAdjustHealthyModel(
|
||||
@ -761,6 +806,51 @@ function expandRectWithMargins(
|
||||
};
|
||||
}
|
||||
|
||||
function expandRectToProviderAspectLimit(
|
||||
rect: NormalizedLocalEditRegion["rect"],
|
||||
sourceWidth: number,
|
||||
sourceHeight: number,
|
||||
maxAspectRatio = 3
|
||||
) {
|
||||
if (
|
||||
!Number.isFinite(sourceWidth) ||
|
||||
!Number.isFinite(sourceHeight) ||
|
||||
sourceWidth <= 0 ||
|
||||
sourceHeight <= 0 ||
|
||||
maxAspectRatio <= 1
|
||||
) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
const pixelWidth = rect.width * sourceWidth;
|
||||
const pixelHeight = rect.height * sourceHeight;
|
||||
if (pixelWidth <= 0 || pixelHeight <= 0) return rect;
|
||||
|
||||
const ratio = pixelWidth / pixelHeight;
|
||||
let nextWidth = rect.width;
|
||||
let nextHeight = rect.height;
|
||||
|
||||
if (ratio > maxAspectRatio) {
|
||||
nextHeight = Math.min(1, pixelWidth / maxAspectRatio / sourceHeight);
|
||||
} else if (ratio < 1 / maxAspectRatio) {
|
||||
nextWidth = Math.min(1, (pixelHeight / maxAspectRatio) / sourceWidth);
|
||||
} else {
|
||||
return rect;
|
||||
}
|
||||
|
||||
const centerX = rect.x + rect.width / 2;
|
||||
const centerY = rect.y + rect.height / 2;
|
||||
const x = clamp(centerX - nextWidth / 2, 0, Math.max(0, 1 - nextWidth));
|
||||
const y = clamp(centerY - nextHeight / 2, 0, Math.max(0, 1 - nextHeight));
|
||||
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
width: nextWidth,
|
||||
height: nextHeight,
|
||||
};
|
||||
}
|
||||
|
||||
function getRectUnion(
|
||||
leftRect: NormalizedLocalEditRegion["rect"],
|
||||
rightRect: NormalizedLocalEditRegion["rect"]
|
||||
@ -938,6 +1028,40 @@ function getScaleAdjustPatchWorkspaceRect(
|
||||
return workspaceRects.reduce((combined, rect) => getRectUnion(combined, rect));
|
||||
}
|
||||
|
||||
function shouldUseScaleAdjustEdgeLockedFullFrameReference(params: {
|
||||
regions: NormalizedLocalEditRegion[];
|
||||
scalePercent?: ScaleAdjustPercent | null;
|
||||
sourceHeight: number;
|
||||
sourceWidth: number;
|
||||
}) {
|
||||
const { regions, scalePercent, sourceHeight, sourceWidth } = params;
|
||||
if (!regions.length || !hasScaleAdjustShrinkTarget(regions, scalePercent)) {
|
||||
return false;
|
||||
}
|
||||
if (!regions.some((region) => isScaleAdjustFurnitureProductLikePrompt(region.prompt))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const workspaceRect = expandRectToProviderAspectLimit(
|
||||
getScaleAdjustPatchWorkspaceRect(regions, scalePercent),
|
||||
sourceWidth,
|
||||
sourceHeight
|
||||
);
|
||||
const pixelWidth = workspaceRect.width * sourceWidth;
|
||||
const pixelHeight = workspaceRect.height * sourceHeight;
|
||||
if (pixelWidth <= 0 || pixelHeight <= 0) return false;
|
||||
|
||||
const ratio = pixelWidth / pixelHeight;
|
||||
const touchesCanvasEdge =
|
||||
workspaceRect.x <= 0.002 ||
|
||||
workspaceRect.y <= 0.002 ||
|
||||
workspaceRect.x + workspaceRect.width >= 0.998 ||
|
||||
workspaceRect.y + workspaceRect.height >= 0.998;
|
||||
const nearProviderAspectLimit = ratio <= 0.42 || ratio >= 2.4;
|
||||
|
||||
return touchesCanvasEdge && nearProviderAspectLimit;
|
||||
}
|
||||
|
||||
function expandPixelRectForCrop(params: {
|
||||
height: number;
|
||||
pixelRect: NormalizedLocalEditRegion["pixelRect"];
|
||||
@ -1336,6 +1460,13 @@ function isScaleAdjustPersonLikePrompt(prompt: string) {
|
||||
);
|
||||
}
|
||||
|
||||
function isScaleAdjustFurnitureProductLikePrompt(prompt: string) {
|
||||
const text = normalizeScaleAdjustModelText(prompt);
|
||||
return /furniture|product|commodity|goods|object|item|subject|sofa|couch|chair|table|desk|cabinet|shelf|bed|bench|lamp|basket|rack|stool|drawer|wardrobe|主物体|主体|物体|商品|产品|家具|沙发|椅|桌|柜|架|床|凳|灯|篮|抽屉|衣柜/.test(
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
function hasScaleAdjustPersonPixelSignal(params: {
|
||||
box: { left: number; top: number; width: number; height: number };
|
||||
raw: Buffer;
|
||||
@ -2781,7 +2912,11 @@ async function createScaleAdjustPatchReference(params: {
|
||||
sourceWidth,
|
||||
userId,
|
||||
} = params;
|
||||
const workspaceRect = getScaleAdjustPatchWorkspaceRect(regions, scalePercent);
|
||||
const workspaceRect = expandRectToProviderAspectLimit(
|
||||
getScaleAdjustPatchWorkspaceRect(regions, scalePercent),
|
||||
sourceWidth,
|
||||
sourceHeight
|
||||
);
|
||||
const workspacePixelRect = rectToPixels(workspaceRect, sourceWidth, sourceHeight);
|
||||
const shouldUseStructureLockedDraft = hasScaleAdjustStructureTarget(
|
||||
regions,
|
||||
@ -3890,7 +4025,7 @@ export async function POST(request: NextRequest) {
|
||||
const useFalScaleAdjustCoordinatePrompt =
|
||||
useScaleAdjustCoordinatePrompt &&
|
||||
resolvedScaleAdjustModelEntry?.provider?.type === "fal-image" &&
|
||||
!useScaleAdjustFullFrameFalEdit;
|
||||
getScaleAdjustModelFamily(resolvedScaleAdjustModelEntry) === "nano-banana-2";
|
||||
const useScaleAdjustVisualLayoutGuide =
|
||||
useScaleAdjustCoordinatePrompt &&
|
||||
!useFalScaleAdjustCoordinatePrompt &&
|
||||
@ -4152,7 +4287,7 @@ export async function POST(request: NextRequest) {
|
||||
const imageRequest: CanvasGenerateImageRequest = {
|
||||
allowFailover: isScaleAdjustOperation ? false : undefined,
|
||||
aspectRatio: scaleAdjustPatchReference
|
||||
? inferClosestAspectRatio(
|
||||
? inferScaleAdjustPatchAspectRatio(
|
||||
scaleAdjustPatchReference.workspacePixelRect.width,
|
||||
scaleAdjustPatchReference.workspacePixelRect.height
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user