Local Canvas workflow
비디오 시퀀스·스프라이트 시트 생성 가이드
연마의 시퀀스 생성기는 짧은 비디오를 브라우저에서 프레임 단위로 읽고, 하나의 PNG 격자 이미지로 배치합니다. 서버에 영상을 올려 변환하는 서비스가 아니라 현재 탭의 HTML 비디오와 Canvas API를 이용하는 로컬 제작 도구입니다.
입력부터 PNG까지 어떤 일이 일어나는가
- 선택한 영상은
URL.createObjectURL()로 현재 브라우저 탭에서만 열립니다. 연마 서버로 업로드하지 않습니다. - 트림 시작·끝, FPS, 가로·세로 칸과 프레임 크기를 읽어 필요한 시점을 계산합니다.
- 각 시점으로 비디오 재생 위치를 옮긴 뒤
drawImage()로 프레임을 Canvas에 복사합니다. - 선택한 루프 모드에 따라 시간 순서를 바꾸거나 시작·끝 프레임을 혼합합니다.
- 완성된 Canvas를 PNG 데이터로 바꿔 사용자의 기기에 다운로드합니다.
이 과정은 영상의 의미나 피사체를 분석하지 않습니다. 카메라 흔들림, 피사체 위치 변화, 조명 점프가 있는지는 사용자가 미리보기로 판단해야 합니다.
세 가지 루프 모드의 실제 차이
| 모드 | 프레임 순서 | 적합한 영상 | 주의할 점 |
|---|---|---|---|
| 직접 연결 | 시작부터 끝까지 순서대로 샘플링 | 처음과 끝 자세가 이미 비슷한 루프 소스 | 끝→처음의 위치·색 차이가 그대로 튈 수 있음 |
| 핑퐁 | 정방향 뒤에 역방향 프레임을 배치 | 연기 팽창·천 흔들림처럼 되감기가 어색하지 않은 동작 | 중간에서 방향이 바뀌며 속도가 꺾여 보일 수 있음 |
| 오버랩 | 마지막 구간을 첫 구간 쪽으로 점진 혼합 | 끝과 시작을 부드럽게 이어야 하는 연속 효과 | 피사체 위치가 크게 다르면 잔상·이중상이 생김 |
오버랩 모드는 “없는 중간 동작을 생성”하지 않습니다. 끝 프레임의 RGBA 값과 대응하는 시작 프레임 값을 선택한 곡선으로 섞는 픽셀 크로스페이드입니다. 따라서 형태가 이동하는 영상보다 같은 위치에서 밝기·밀도만 변하는 효과에 더 잘 맞습니다.
그리드와 해상도 계산 예시
스프라이트 시트 전체 크기는 가로 칸 × 프레임 너비, 세로 칸 × 프레임 높이로 계산합니다. 예를 들어 4×4 그리드와 128×128px 프레임을 선택하면 16프레임이 512×512px PNG 한 장에 배치됩니다.
| 설정 | 프레임 수 | 출력 크기 | RGBA 작업 메모리의 단순 하한 |
|---|---|---|---|
| 4×4, 128px | 16 | 512×512px | 약 1MiB |
| 8×8, 128px | 64 | 1024×1024px | 약 4MiB |
| 8×8, 256px | 64 | 2048×2048px | 약 16MiB |
| 16×16, 512px | 256 | 8192×8192px | 약 256MiB |
표의 메모리는 결과 Canvas 한 장의 가로×세로×4바이트만 계산한 하한입니다. 비디오 디코딩 버퍼, 오버랩용 프레임 배열과 마스크가 더해지므로 실제 사용량은 더 큽니다. 모바일에서는 4×4 또는 8×8과 128px 프레임부터 확인하는 편이 안전합니다.
자동 계산을 정확히 해석하는 법
자동 계산은 트림 길이 × FPS를 반올림해 목표 프레임 수를 만들고, 그 수가 들어갈 정사각형에 가까운 가로·세로 격자를 고릅니다. 최대치는 16×16, 즉 256칸입니다. 격자 칸 수가 계산한 목표보다 조금 많으면 생성 단계는 그 격자 전체를 채우므로, 정확한 프레임 수가 중요한 엔진에서는 가로·세로 값을 직접 조정하세요.
FPS는 “원본 영상 FPS를 보존한다”는 뜻이 아니라 어느 시간 간격으로 프레임을 읽을지 정하는 샘플링 값입니다. 1초 구간을 16FPS로 읽어 4×4 격자에 담으면 계산과 칸 수가 정확히 16으로 맞습니다.
마스크와 크로스페이드에서 확인할 점
- 업로드 마스크는 알파 채널이 있는 PNG가 가장 예측하기 쉽습니다.
- 마스크 반전은 남길 영역과 지울 영역을 뒤집습니다. 원본 영상 자체를 수정하지 않습니다.
- Linear는 일정한 속도로 혼합하고, Ease 계열은 혼합 비율이 변하는 속도만 바꿉니다.
- 프레임 인덱스 표시는 디버깅용 글자를 결과 이미지에 직접 그립니다. 최종 배포본을 만들기 전 반드시 끄세요.
- 출력 PNG에는 FPS·그리드·피벗 같은 엔진 메타데이터가 포함되지 않습니다. 게임 엔진에서 별도로 입력해야 합니다.
실패 조건과 해결 순서
영상은 선택했지만 열리지 않음
파일 확장자보다 브라우저가 내부 코덱을 해독할 수 있는지가 중요합니다. MP4 컨테이너라도 지원되지 않는 코덱이면 실패할 수 있습니다. 우선 H.264 영상으로 다시 인코딩하고, 10초 이내·1920×1080 이하의 짧은 파일로 재현하세요.
생성 중 탭이 느려지거나 종료됨
격자, 프레임 크기와 오버랩 프레임을 한 번에 낮춥니다. 16×16·512px처럼 큰 설정은 결과 Canvas만으로도 상당한 메모리를 사용합니다. 모바일에서는 다른 탭을 닫고 작은 프리셋으로 먼저 성공 여부를 확인하세요.
루프 경계에 이중상이 생김
오버랩 프레임을 늘리기 전에 트림 구간부터 다시 잡습니다. 시작·끝의 피사체 위치가 비슷한 구간을 선택한 뒤 작은 오버랩부터 늘려야 원인을 구분할 수 있습니다.
개인정보와 브라우저 한계
영상과 마스크는 연마 서버로 전송하지 않습니다. 다만 사용자가 다운로드한 PNG와 브라우저의 최근 파일 기록은 기기에 남을 수 있습니다. 공용 기기에서는 다운로드 파일을 직접 삭제하세요.
브라우저 API 동작은 브라우저·운영체제·코덱에 따라 달라집니다. 연마는 Chrome 계열 최신 버전을 우선 확인하지만 모든 기기에서 같은 디코딩 결과나 최대 Canvas 크기를 보장하지 않습니다.
구현 참고: MDN, CanvasRenderingContext2D.drawImage() · MDN, URL.createObjectURL()