auto-save 2026-05-14 06:27 (~4)

This commit is contained in:
2026-05-14 06:28:04 +08:00
parent 2d36adafd3
commit 6480d69c63
4 changed files with 50 additions and 35 deletions

View File

@@ -448,7 +448,7 @@ def run(cmd: list[str], cwd: Path | None = None) -> str:
# ---- 启发式选帧工具 ----
import imagehash
import numpy as np
from PIL import Image, ImageEnhance, ImageFilter, ImageOps
from PIL import Image, ImageChops, ImageEnhance, ImageFilter, ImageOps
def _sharpness_from_gray(g: np.ndarray) -> float:
@@ -592,6 +592,7 @@ def _normalize_asset_image(
size: AssetSize,
background: AssetBackground = "white",
square: bool = False,
fill_subject: bool = False,
) -> tuple[int, int]:
import io as _io
target_w, target_h = _asset_target_size(source_path, size, square=square)
@@ -599,7 +600,25 @@ def _normalize_asset_image(
out_path.parent.mkdir(parents=True, exist_ok=True)
with Image.open(_io.BytesIO(img_bytes)) as raw:
img = raw.convert("RGB")
img.thumbnail((target_w, target_h), Image.Resampling.LANCZOS)
if fill_subject:
diff = ImageChops.difference(img, Image.new("RGB", img.size, bg))
mask = diff.convert("L").point(lambda px: 255 if px > 18 else 0)
bbox = mask.getbbox()
if bbox:
left, top, right, bottom = bbox
pad_x = round((right - left) * 0.06)
pad_y = round((bottom - top) * 0.06)
img = img.crop((
max(0, left - pad_x),
max(0, top - pad_y),
min(img.width, right + pad_x),
min(img.height, bottom + pad_y),
))
max_w = max(1, round(target_w * 0.92))
max_h = max(1, round(target_h * 0.94))
img.thumbnail((max_w, max_h), Image.Resampling.LANCZOS)
else:
img.thumbnail((target_w, target_h), Image.Resampling.LANCZOS)
canvas = Image.new("RGB", (target_w, target_h), bg)
canvas.paste(img, ((target_w - img.width) // 2, (target_h - img.height) // 2))
canvas.save(out_path, "JPEG", quality=95)
@@ -699,6 +718,8 @@ SUBJECT_VIEW_LABELS: dict[str, str] = {
"back": "背面",
"left": "左侧",
"right": "右侧",
"three_quarter_left": "左前 45°",
"three_quarter_right": "右前 45°",
"side": "侧面",
"side_walk": "侧面走路",
"top": "顶部视角",
@@ -727,10 +748,10 @@ def _subject_view_labels(kind: SubjectKind, requested: list[str] | None = None)
return [
("front", "正面站立"),
("back", "背面站立"),
("side", "站立"),
("side_walk", "侧面走路"),
("expression_neutral", "中性表情"),
("expression_relaxed", "放松表情"),
("left", "侧站立"),
("right", "右侧站立"),
("three_quarter_left", "左前 45° 站立"),
("three_quarter_right", "右前 45° 站立"),
]
return [
("front", "正面"),