53 lines
2.4 KiB
Python
53 lines
2.4 KiB
Python
"""④ analyze — 검수 게이트에 올릴 재료를 만든다.
|
|
|
|
여기서 사람이 움직일 요소를 확정하고, 그 승인이 14크레딧 지출을 확정한다.
|
|
실제 프롬프트는 ⑤ motion에서 사람이 고른 키로 다시 쓴다.
|
|
"""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
from PIL import Image
|
|
|
|
from models.analysis import FixedLayer, MotionChoice, PosterAnalysis
|
|
from services.motion import plan_motion
|
|
from utils.higgsfield import KLING_3_0
|
|
from utils.image import review_grid_overlay
|
|
|
|
MOTION_LABELS = {
|
|
"ray": "광선", "snow": "눈", "fog": "안개", "glow": "발광", "light": "조명",
|
|
"star": "별", "cloud": "구름", "smoke": "연기", "water": "물", "wave": "파도",
|
|
"moon": "달", "sun": "해", "flag": "깃발", "foliage": "나뭇잎", "vessel": "배",
|
|
"crowd": "사람 무리", "wheel": "바퀴·관람차", "firework": "불꽃놀이",
|
|
}
|
|
FIXED_LABELS = {"title": "제목", "logo": "로고", "date": "일시",
|
|
"person": "인물", "sponsor": "후원 바"}
|
|
|
|
# veo·seedance가 디즈니 IP 작품을 거부한 이력이 있어, 크레딧을 쓰기 전에 경고만 띄운다.
|
|
# 한국어 표기 몇 개만 보는 어림짐작이라 판정이 아니다.
|
|
IP_RISK_PATTERN = re.compile(r"디즈니|겨울왕국|라이온킹|알라딘|마블")
|
|
|
|
|
|
def motion_choices(kept, dropped) -> list[MotionChoice]:
|
|
"""VLM이 고른 것은 켜고, 확신 없어 탈락한 것은 꺼서 함께 보여준다."""
|
|
chosen = {item.motion for item in kept}
|
|
choices = [MotionChoice(key=item.motion, label=MOTION_LABELS.get(item.motion, item.motion),
|
|
what=item.what, on=True) for item in kept]
|
|
choices += [MotionChoice(key=item.motion, label=MOTION_LABELS.get(item.motion, item.motion),
|
|
what=item.what, on=False)
|
|
for item in dropped if item.motion not in chosen]
|
|
return choices
|
|
|
|
|
|
async def analyze_poster(poster: Path | Image.Image, title: str = "") -> PosterAnalysis:
|
|
source = (Image.open(poster) if isinstance(poster, Path) else poster).convert("RGB")
|
|
plan = await plan_motion(source)
|
|
return PosterAnalysis(
|
|
grid=review_grid_overlay(source),
|
|
movable=motion_choices(plan.kept, plan.dropped),
|
|
fixed=[FixedLayer(key=key, label=label) for key, label in FIXED_LABELS.items()],
|
|
model=KLING_3_0,
|
|
ip_risk=bool(IP_RISK_PATTERN.search(title)),
|
|
has_qr=plan.has_qr,
|
|
plan=plan,
|
|
)
|