음성 재생과 운영 배포 정리

This commit is contained in:
Yun Chan 2026-06-28 12:18:20 +09:00
parent 8ed185ce6c
commit ac7db95542
1020 changed files with 46863 additions and 2175 deletions

View file

@ -0,0 +1,68 @@
from __future__ import annotations
import shutil
from pathlib import Path
from PIL import Image
ROOT = Path(__file__).resolve().parents[3]
CANVAS = (900, 1125)
MALE_PERSONAS = ("P5", "P7")
MALE_EMPTY_HAIR_SLOTS = (
"hair-back-base",
"hair-back-left",
"hair-back-right",
"hair-side-left-2",
"hair-side-right-2",
)
GENERATED_PERSONAS = ("P4", "P5", "P6", "P7")
def parts_dir(persona: str) -> Path:
return ROOT / f"apps/web/public/avatar/{persona.lower()}-live2d-generated/parts"
def write_empty(path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
Image.new("RGBA", CANVAS, (0, 0, 0, 0)).save(path, optimize=True)
def clean_green_edge_spill(path: Path) -> int:
image = Image.open(path).convert("RGBA")
pixels = image.load()
changed = 0
for y in range(image.height):
for x in range(image.width):
r, g, b, a = pixels[x, y]
if a <= 80 and g > 135 and g > r + 35 and g > b + 35:
if a <= 48:
pixels[x, y] = (r, g, b, 0)
else:
pixels[x, y] = (r, min(g, max(r, b) + 18), b, a)
changed += 1
if changed:
image.save(path, optimize=True)
return changed
def main() -> int:
for persona in MALE_PERSONAS:
directory = parts_dir(persona)
for part_id in MALE_EMPTY_HAIR_SLOTS:
write_empty(directory / f"{part_id}.png")
p7_outfit = parts_dir("P7") / "outfit.png"
p5_outfit = parts_dir("P5") / "outfit.png"
if p7_outfit.exists():
shutil.copyfile(p7_outfit, p5_outfit)
cleaned = 0
for persona in GENERATED_PERSONAS:
for path in parts_dir(persona).glob("*.png"):
cleaned += clean_green_edge_spill(path)
print(f"applied visual overrides for P5/P7 male silhouette; cleaned {cleaned} green edge pixels")
return 0
if __name__ == "__main__":
raise SystemExit(main())