49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
from dataclasses import dataclass
|
|
|
|
from PIL import Image
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
Rect = tuple[float, float, float, float]
|
|
|
|
|
|
class MaskSpec(BaseModel):
|
|
"""rect — 사각 전체 고정(밝은 배경 포스터. 베벨·그림자까지 덮는다).
|
|
glyph — 사각 안 글자 픽셀만. 검정 포스터용이며 register와 함께 써야 한다."""
|
|
mode: str = "rect"
|
|
ink_min: int = 55
|
|
thin_dilate: int = 9
|
|
thick_dilate: int = 25
|
|
thick_from_y: float = 0.85
|
|
|
|
|
|
class HybridSpec(BaseModel):
|
|
# register는 BaseModel 속성과 겹쳐 이름을 바꾸고 alias로 원본 키를 받음
|
|
model_config = ConfigDict(populate_by_name=True)
|
|
|
|
clip: str | None = None
|
|
clip_crop: str | None = None # "x0,y0,w,h" — 9:16 캔버스에 얹힌 클립용
|
|
register_frames: bool = Field(False, alias="register")
|
|
|
|
|
|
class LayerConfig(BaseModel):
|
|
"""작품별 좌표. 아직 사람이 손으로 쓴다 — 신규 공연은 여기서 멈추는 게 정상이다."""
|
|
mask: MaskSpec = MaskSpec()
|
|
fixed_rects: list[Rect] = []
|
|
sil_box: Rect = (0.0, 0.0, 0.0, 0.0)
|
|
sil_poly: list[tuple[float, float]] = []
|
|
glyphs: dict[str, Rect] = {}
|
|
sweep_at: dict[str, float] = {}
|
|
punches: list[tuple[Rect, float, float]] = [] # (사각, 시작초, 피크배율)
|
|
glows: list[tuple[Rect, float]] = []
|
|
protect: list[Rect] = []
|
|
glyph_dark_ink: bool = True
|
|
hybrid: HybridSpec = Field(default_factory=HybridSpec)
|
|
|
|
|
|
@dataclass
|
|
class HybridResult:
|
|
video: bytes
|
|
frames: int
|
|
duration: float
|
|
proof: Image.Image | None = None # 8시점 컨택트 시트
|