playreel/backend/models/detail_section.py
Haewon Kam 0e53fa294b fix(compose): 상세페이지 스크롤을 롱이미지로 되돌린다
조각을 화면에 얹는 방식이라 스크롤이 한 번도 일어나지 않았다.
심규선 상세페이지 실측 — 19조각 중 1920px를 넘는 것이 0개라
scroll_scene의 span이 항상 0이었다. 화면의 13~44%만 조각이고
나머지는 블러 포스터로 남았으며, 같은 정지컷이 6초 넘게 이어졌다.

정본(tech_spec §5)에 있던 extend_to_height가 이식에서 빠진 것이 원인이다.
그것이 없으니 조각이 짧을 때 블러 배경에 상단 정렬로 얹는 수밖에 없었다.

- to_surface: 롱이미지를 폭 1080으로. trim_blank를 태우지 않는다 —
  위를 깎으면 섹션 y좌표가 전부 어긋난다
- extend_to_height + blank_band: 글자 없는 배경 띠를 거울 타일링,
  이음매 페더 40px. 프레임보다 짧아도 풀프레임을 채운다
- scroll_scene: 배경 합성 없이 surface.crop() — 블러가 섞일 여지를 없앤다
- build_scene_plan: 섹션은 훑기 시작점, 큐 길이가 훑는 거리.
  섹션이 떨어지면 앞 씬이 멈춘 자리에서 이어 읽는다(커서)
- SCROLL_TAG_PRIORITY에서 notice·crossbanner 제거 — 약관을 읽히는 영상이 아니다
- final_checks: 씬 종류가 scroll이라고 적힌 것이 아니라 실제 이동 거리를 본다.
  이 검사가 물러서 0픽셀 스크롤이 게이트를 통과했다

실측(심규선 자산 전체 합성, 569프레임 23.72초):
  콘텐츠 비율 t=8s 23%→99% · t=11s 13%→92% · t=17s 44%→99%
  프레임 간 변화량 0.01(정지) → 22~31

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 15:24:58 +09:00

27 lines
643 B
Python

from dataclasses import dataclass
from PIL import Image
UNTAGGED = "untagged"
@dataclass
class DetailSection:
source: str # 잘라낸 원본 이름 (detail_01 …)
index: int # 그 원본 안에서의 순번
y0: int
y1: int
# compose는 좌표만 쓴다 — 조각 그림 없이 만들어도 된다
image: Image.Image | None = None
tag: str = UNTAGGED
@property
def name(self) -> str:
return f"{self.source}_s{self.index:02d}"
@dataclass
class DetailSplitResult:
sections: list[DetailSection]
sheet: Image.Image # 육안 검수용 컨택트 시트