fix: composite full-frame scale edits

This commit is contained in:
134 2026-07-05 21:52:48 +08:00
parent c3d8c5d56c
commit 14e75197cf
2 changed files with 40 additions and 16 deletions

View File

@ -3357,13 +3357,21 @@ async function createScaleAdjustPatchReference(params: {
const targetDraftBuffer = targetDraftReference.buffer;
const suffix = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
if (params.fullFrameReferenceOnly && structureLockAppliedRef.value) {
const targetDraftFullUpload = await uploadFile(
`canvas-scale-adjust-full-target-draft-${suffix}.png`,
toArrayBuffer(targetDraftBuffer)
);
const [targetDraftFullUpload, compositeClipMaskUpload] = await Promise.all([
uploadFile(
`canvas-scale-adjust-full-target-draft-${suffix}.png`,
toArrayBuffer(targetDraftBuffer)
),
targetDraftReference.compositeClipMaskBuffer
? uploadFile(
`canvas-scale-adjust-composite-clip-mask-${suffix}.png`,
toArrayBuffer(targetDraftReference.compositeClipMaskBuffer)
)
: Promise.resolve(null),
]);
return {
compositeClipMaskUrl: null,
compositeClipMaskUrl: compositeClipMaskUpload?.url || null,
sourceCropUrl: sourceImageUrl || targetDraftFullUpload.url,
structureLockedDraft: structureLockAppliedRef.value,
targetDraftFullUrl: targetDraftFullUpload.url,
@ -5048,8 +5056,7 @@ export async function POST(request: NextRequest) {
: "locked-plate-semantic-target-map-no-old-crop-v15"
: undefined,
scaleAdjustPostCompositeApplied:
Boolean(scaleAdjustPatchReference) &&
!useScaleAdjustFullFrameStructurePatch,
Boolean(scaleAdjustPatchReference),
scaleAdjustUsesFullFrameOutput:
isScaleAdjustOperation &&
(!scaleAdjustPatchReference || useScaleAdjustFullFrameStructurePatch),
@ -5087,7 +5094,7 @@ export async function POST(request: NextRequest) {
? { maskImageUrl: scaleAdjustEditMaskUpload.url }
: undefined,
referenceImages,
scaleAdjustPatchComposite: scaleAdjustPatchReference && !useScaleAdjustFullFrameStructurePatch
scaleAdjustPatchComposite: scaleAdjustPatchReference
? {
diffAlphaCutoff:
scaleAdjustPatchReference.structureLockedDraft ? 24 : 8,
@ -5103,6 +5110,9 @@ export async function POST(request: NextRequest) {
scaleAdjustPatchReference.structureLockedDraft ? 36 : 42,
featherMinPx: 10,
featherRatio: 0.018,
generatedFrame: useScaleAdjustFullFrameStructurePatch
? "full"
: "workspace",
maskMode: "diff",
regions: scaleAdjustPatchCompositeRegions,
sourceImageUrl,

View File

@ -56,6 +56,7 @@ export interface CanvasLocalEditCompositeConfig {
export interface CanvasScaleAdjustPatchCompositeConfig {
clipMaskImageUrl?: string;
generatedFrame?: "workspace" | "full";
sourceImageUrl: string;
workspaceRegion: CanvasLocalEditCompositeRegion;
regions?: CanvasLocalEditCompositeRegion[];
@ -536,6 +537,7 @@ function normalizeScaleAdjustPatchCompositeConfig(
max: 0.12,
min: 0,
}),
generatedFrame: value.generatedFrame === "full" ? "full" : "workspace",
};
}
@ -3039,14 +3041,25 @@ async function applyScaleAdjustPatchCompositeToImages(params: {
for (const [index, image] of images.entries()) {
const generatedUrl = image.originalUrl || image.thumbnailUrl;
const generatedBuffer = await fetchImageBufferFromUrl(generatedUrl);
const resizedGeneratedBuffer = await sharp(generatedBuffer, { failOn: "none" })
.rotate()
.resize(workspaceBox.width, workspaceBox.height, {
fit: "cover",
position: "center",
})
.png({ compressionLevel: 6 })
.toBuffer();
const resizedGeneratedBuffer =
composite.generatedFrame === "full"
? await sharp(generatedBuffer, { failOn: "none" })
.rotate()
.resize(sourceWidth, sourceHeight, {
fit: "cover",
position: "center",
})
.extract(workspaceBox)
.png({ compressionLevel: 6 })
.toBuffer()
: await sharp(generatedBuffer, { failOn: "none" })
.rotate()
.resize(workspaceBox.width, workspaceBox.height, {
fit: "cover",
position: "center",
})
.png({ compressionLevel: 6 })
.toBuffer();
const diffPatchMask =
composite.maskMode === "diff"
? await buildLocalEditDiffCompositeMask({
@ -3139,6 +3152,7 @@ async function applyScaleAdjustPatchCompositeToImages(params: {
imageCount: mergedImages.length,
customClipMaskApplied: Boolean(customClipPatchMaskRaw),
diffRegionClipApplied: Boolean(regionClipPatchMask),
generatedFrame: composite.generatedFrame || "workspace",
maskMode: composite.maskMode || "workspace",
maskRegionCount: maskRegionBoxes?.length || 0,
sourceHeight,