fix(inpaint): free mode scales both axes on the max_size clamp (no stretch)

Free-mode output capped each axis independently, so a wide/tall crop whose
long side exceeded max_size came out stretched (4:1 source -> ~1.4:1). Now
both axes scale by one factor, preserving the source aspect. Mirrored in
geometry.mjs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
pixaroma
2026-06-16 14:49:59 +03:00
co-authored by Claude Opus 4.8
parent a11a8fb208
commit 1fab59686b
2 changed files with 19 additions and 4 deletions
+7 -2
View File
@@ -63,8 +63,13 @@ export function computeRegion(bbox, W, H, params) {
if (mode === "force") {
out_w = tw; out_h = th;
} else if (mode === "free") {
out_w = Math.min(roundMult(rw_i, mult), roundMult(p.max_size, mult));
out_h = Math.min(roundMult(rh_i, mult), roundMult(p.max_size, mult));
// keep the cropped rect's own size; when the long side exceeds max_size scale
// BOTH axes by one factor so the aspect is preserved (mirror of compute_region).
let ow = rw_i, oh = rh_i;
const big = Math.max(ow, oh);
if (big > p.max_size) { const k = p.max_size / big; ow *= k; oh *= k; }
out_w = roundMult(ow, mult);
out_h = roundMult(oh, mult);
} else {
const long = Math.max(rw_i, rh_i);
let s = long > 0 ? p.target / long : 1;
+12 -2
View File
@@ -286,8 +286,18 @@ def compute_region(bbox, W, H, p):
if mode == "force":
out_w, out_h = tw, th
elif mode == "free":
out_w = min(_round_mult(rw_i, mult), _round_mult(p["max_size"], mult))
out_h = min(_round_mult(rh_i, mult), _round_mult(p["max_size"], mult))
# free = "multiple only": keep the cropped rect's own size, just round to the
# multiple. When the LONG side exceeds max_size, scale BOTH axes by one factor
# (not each axis independently) so the output keeps the source aspect - an
# independent per-axis cap stretched a wide/tall crop. No min_size bump (free
# preserves the source size; only the max ceiling applies).
ow, oh = float(rw_i), float(rh_i)
big = max(ow, oh)
if big > p["max_size"]:
k = p["max_size"] / big
ow *= k; oh *= k
out_w = _round_mult(ow, mult)
out_h = _round_mult(oh, mult)
else: # keep shape: scale the CROPPED rect's long side to target, keep aspect
long_side = max(rw_i, rh_i)
s = p["target"] / long_side if long_side > 0 else 1.0