From 19c4367fb8622e9b51fbb9c6c2a54a9531a48405 Mon Sep 17 00:00:00 2001 From: 134 Date: Sat, 4 Jul 2026 19:05:52 +0800 Subject: [PATCH] fix: clip protected person pixels without dropping scale target --- app/api/canvas/local-edit/route.ts | 32 +++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts index 409144035..ef5a0c359 100644 --- a/app/api/canvas/local-edit/route.ts +++ b/app/api/canvas/local-edit/route.ts @@ -1700,15 +1700,29 @@ function filterScaleAdjustStructureComponents(params: { : false; const protectedPersonOverlapRatio = protectedPersonOverlap / Math.max(1, area); + const shouldClipProtectedPersonSide = + Boolean(protectedPersonMask) && + protectedPersonOverlap > 0 && + touchesProtectedPersonSide; + const isProtectedPersonPixel = (pixelX: number, pixelY: number) => { + const pixelIndex = pixelY * width + pixelX; + if (protectedPersonMask?.[pixelIndex]) return true; + if (!shouldClipProtectedPersonSide) return false; + if (protectedPersonSide === "right") return pixelX >= width * 0.78; + if (protectedPersonSide === "left") return pixelX <= width * 0.22; + if (protectedPersonSide === "auto") { + return ( + (touchesRight && pixelX >= width * 0.82) || + (touchesLeft && pixelX <= width * 0.18) + ); + } + return false; + }; const likelyProtectedPersonComponent = Boolean(protectedPersonMask) && protectedPersonOverlap > 0 && - (protectedPersonOverlapRatio >= 0.012 || - (touchesProtectedPersonSide && - protectedPersonOverlap >= Math.max(6, area * 0.002))) && - (touchesProtectedPersonSide || - componentHeight >= height * 0.16 || - componentWidth >= width * 0.16); + touchesProtectedPersonSide && + protectedPersonOverlapRatio >= 0.32; const broadTopBackground = touchesTop && centerYRatio <= 0.45 && @@ -1740,12 +1754,16 @@ function filterScaleAdjustStructureComponents(params: { if (fillSurfaceComponent) { for (let fillY = minY; fillY <= maxY; fillY += 1) { for (let fillX = minX; fillX <= maxX; fillX += 1) { + if (isProtectedPersonPixel(fillX, fillY)) continue; output[fillY * width + fillX] = 255; } } } else { for (let index = 0; index < queueX.length; index += 1) { - output[(queueY[index] || 0) * width + (queueX[index] || 0)] = 255; + const pixelX = queueX[index] || 0; + const pixelY = queueY[index] || 0; + if (isProtectedPersonPixel(pixelX, pixelY)) continue; + output[pixelY * width + pixelX] = 255; } } }