이미지 시퀀스를 ffmpeg로 MP4로 만들 때 색이 바뀐다면: 명령 생성기
렌더한 PNG 시퀀스를 ffmpeg로 MP4로 바꿨는데 색이 회색으로 뜨거나 파일이 재생되지 않으면 코덱부터 바꾸기 쉽습니다. 하지만 파일명과 프레임레이트, 픽셀 변환, 색 태그는 서로 다른 문제입니다. 먼저 이 네 가지를 나눠 확인해야 합니다. 그런데 BT.709 태그를 붙였는데도 픽셀 색이 왜 달라질까요?
아래 명령 생성기에 시퀀스 패턴, 시작 번호, fps를 넣으면 H.264 MP4 또는 ProRes 422 HQ MOV 명령을 만듭니다. 이 도구는 브라우저 안에서 명령 문자열만 만들며, 렌더 파일을 읽거나 서버로 보내지 않습니다.
이미지 시퀀스 → ffmpeg 명령 생성기
PNG는 기본으로 sRGB 표시 신호라고 가정해. 표시 변환이 끝난 EXR은 입력 전달 특성을 맞춰. 이 도구는 파일을 읽거나 업로드하지 않아.
scene-linear EXR은 아래 명령만으로 화면용 SDR 색이 되지 않아. 렌더러나 OCIO에서 표시 변환을 먼저 적용해. 표시 변환이 끝난 EXR만 확인 상자를 선택하고, 입력 전달 특성도 맞춰.
패턴의 번호 자리는 %04d, ####, $F4 중 하나로 넣어.
첫 명령은 PNG 패턴을 24fps로 읽고, H.264와 yuv420p를 선택해 MP4를 만듭니다. ProRes를 고르면 422 HQ 프로파일과 MOV 컨테이너를 씁니다. 출력 확장자는 선택한 형식에 따라 붙습니다.
1. ffmpeg 이미지 시퀀스는 번호와 fps부터 맞춥니다
파일명이 beauty.1001.png부터 시작한다면 패턴은 beauty.%04d.png, 시작 번호는 1001입니다. ####나 Houdini의 $F4도 도구가 %04d로 바꿉니다. 실제 파일이 1부터 시작하는데 1001을 넣으면 입력 파일을 찾지 못합니다.
-framerate와 -start_number는 -i 앞에 둡니다. 둘 다 시퀀스를 읽는 입력 쪽 옵션입니다. -framerate 24는 초당 24장을 읽으라는 뜻이고, -start_number 1001은 첫 파일 번호를 지정합니다. 프레임레이트가 잘못되면 재생 속도와 길이도 달라집니다.
번호가 빠지면 그 다음 프레임을 자동으로 건너뛴다고 가정하지 마세요. 로컬에서 1001번과 1003번만 둔 시퀀스를 변환하자 출력은 1001번 한 프레임에서 끝났습니다. 변환 전에 첫 번호·마지막 번호·파일 수를 확인하세요. 영상에 소리가 필요하면 별도 오디오 입력을 추가해야 합니다. 이 생성기는 이미지 시퀀스의 영상만 만듭니다.
2. MP4 재생 문제는 코덱과 픽셀 형식을 함께 봅니다
MP4라는 확장자는 컨테이너 이름입니다. 안에 든 영상 코덱과 픽셀 형식까지 보장하지 않습니다. 범용 재생이 목적이면 도구의 H.264 MP4 선택이 시작점입니다. 이 명령은 libx264로 인코딩하고 yuv420p로 저장합니다.
yuv420p는 영상 플레이어 호환성이 높은 8비트 4:2:0 형식입니다. 색차 해상도를 줄이는 방식이라 픽셀 값이 원본과 완전히 같지는 않습니다. 또 홀수 크기의 프레임은 출력 크기가 달라질 수 있습니다. 319×239 PNG를 이 H.264 경로에 넣은 시험에서는 파일은 만들어졌지만 결과가 318×238이었습니다. 프레임 가장자리가 중요하면 렌더 해상도를 짝수로 맞추세요.
합성 중간 파일이나 다음 작업자에게 넘길 파일이면 ProRes가 더 알맞을 수 있습니다. ProRes 422 HQ는 중간 작업용 10비트 4:2:2 형식입니다. 이 생성기는 H.264 yuv420p와 ProRes 422 HQ를 출력하며, 둘 다 알파를 보존하지 않습니다. 투명도가 필요하면 ProRes 4444와 알파 지원 픽셀 형식을 쓰는 별도 명령이 필요합니다. 코덱 차이는 ProRes와 H.264를 고르는 기준에서 이어서 확인할 수 있습니다.
3. 색 태그와 RGB→YUV 변환은 다른 일입니다
MP4 색이 달라졌을 때 -color_primaries bt709, -color_trc bt709, -colorspace bt709만 추가하면 충분하다고 생각하기 쉽습니다. 이 옵션은 영상의 색 원색, 전달 특성, YCbCr 행렬을 플레이어에 알려 줍니다. 태그만으로 이미지를 BT.709 픽셀로 바꾸지는 않습니다. 특히 sRGB와 BT.709는 원색은 같지만 전달 특성이 다르므로, -color_trc bt709만 붙여서는 sRGB 픽셀이 변환되지 않습니다.
실제 색 변환은 -vf의 zscale에서 지정합니다. 입력이 sRGB라면 transferin=iec61966-2-1로 밝기 전달 특성을 읽고, transfer=709로 BT.709 출력에 맞춥니다. matrixin=gbr은 RGB 입력, matrix=709는 YUV 출력 행렬입니다. rangein=full:range=limited는 신호 범위를 변환합니다. 마지막 format이 인코더에 넘길 픽셀 형식을 고릅니다.
| 명령 부분 | 하는 일 | 맞지 않을 때 |
|---|---|---|
zscale=...matrixin=gbr:matrix=709 | RGB 입력을 BT.709 YUV 매트릭스로 변환 | 색조나 채도가 달라질 수 있음 |
rangein=full:range=limited | 입력·출력 신호 범위를 변환 | 검정이 뜨거나 어두운 값이 뭉개질 수 있음 |
-color_range tv | 출력이 limited range라고 파일에 표시 | 플레이어가 범위를 잘못 해석할 수 있음 |
-colorspace / -color_trc / -color_primaries | 행렬·전달 특성·원색 태그를 기록 | 신호와 태그가 다르면 다른 화면에서 색이 달라 보일 수 있음 |
format=yuv420p | H.264 재생 호환성이 높은 픽셀 형식을 선택 | 지원하지 않는 형식이면 재생이 안 될 수 있음 |
비디오 레인지 8비트 Y′ 신호의 기준 검정·흰색은 보통 16과 235입니다. 이 수치는 RGB 각 채널에 그대로 적용하는 값이 아닙니다. 잘못된 레인지 태그를 고치는 일과, 픽셀 값을 다른 레인지로 다시 매핑하는 일도 구분해야 합니다. 자세한 숫자는 비디오 레벨 16–235와 풀 레인지를 참고하세요.
601과 709 행렬을 서로 다르게 읽으면 밝기뿐 아니라 색 성분 복원도 달라집니다. HD 파일이라고 자동으로 모든 단계가 709로 변환되는 것은 아닙니다. Rec.601·Rec.709 행렬 착오가 색을 바꾸는 사례처럼 인코딩과 디코딩 행렬이 같은지 확인하세요.
4. 로컬 ffmpeg로 만든 파일의 태그와 픽셀을 비교했습니다
Windows의 FFmpeg 2022-07-21 빌드에서 색 패치가 들어간 RGB PNG 시퀀스를 sRGB 입력으로 지정해 두 명령으로 변환했습니다. 시작 번호 1001, 24fps를 넣고 H.264와 ProRes 출력의 ffprobe 정보 및 디코드한 첫 프레임을 다시 sRGB로 변환한 값을 비교했습니다.
| 출력 | ffprobe 결과 | 입력 패치 → 디코드 후 |
|---|---|---|
| H.264 MP4 | yuv420p, tv, bt709 원색·전달·행렬 | 184,122,86 → 183,122,85 16,128,235 → 16,129,235 |
| ProRes 422 HQ MOV | yuv422p10le, tv, bt709 원색·전달·행렬 | 184,122,86 → 184,122,86 16,128,235 → 16,128,235 |
비교할 때 MP4/MOV를 디코드한 뒤 BT.709 신호를 같은 sRGB 전달 특성으로 되돌렸습니다. H.264에서는 두 표본이 채널별 최대 1 코드 달라졌고 ProRes 표본은 같았습니다. 이 실행은 해당 합성 패치의 왕복 결과를 확인한 테스트이지, 실제 플레이트와 모든 플레이어의 화면 표시까지 보장하지는 않습니다.
내 파일의 코덱·픽셀 형식·색 태그는 다음처럼 확인할 수 있습니다. 출력이 기대와 다르면 이 값과 실제 시퀀스 조건을 함께 봅니다.
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,pix_fmt,color_range,color_space,color_transfer,color_primaries -of default=noprint_wrappers=1 output.mp4
ProRes는 이 PC의 FFmpeg 빌드에서 setparams로 프레임 속성을 지정하고 출력 태그를 함께 기록한 뒤 color_range=tv, color_space=bt709, color_transfer=bt709, color_primaries=bt709로 확인됐습니다. 생성 명령에는 실험적 write_colr 플래그를 넣지 않았습니다. 빌드에 따라 태그 기록 동작이 다를 수 있어, ProRes 결과도 ffprobe로 확인하세요.
선형 EXR은 색 태그보다 먼저 표시 변환을 확인합니다
OpenEXR은 보통 화면용으로 톤 매핑하기 전의 장면 기준 선형 값을 저장합니다. 선형 값은 빛의 양에 비례하지만, MP4 플레이어는 그 값만 보고 어떤 OCIO view나 룩을 적용해야 하는지 알 수 없습니다. 파일에 BT.709 태그를 붙이는 것만으로 렌더의 표시 변환이 생기지는 않습니다.
그래서 scene-linear EXR을 바로 H.264로 넣으면 검거나 밝기가 맞지 않는 결과가 나올 수 있습니다. 렌더러나 Nuke, After Effects 등 색관리 환경에서 프로젝트에 맞는 display/view transform을 먼저 적용한 뒤 인코딩하세요. 표시 변환이 이미 들어 있는 EXR은 도구에서 그 상태를 확인하고 입력 전달 특성을 선택해야 합니다. OpenEXR 형식은 선형 저장을 의도하지만 강제하지 않습니다.
색이 바뀌면 태그보다 픽셀 변환부터 맞춥니다
H.264 MP4의 색을 맞출 때는 RGB→YUV 행렬과 레인지를 실제 픽셀에 적용하고, 출력 태그와 yuv420p를 그 결과에 맞춰 기록하세요. 태그는 신호를 설명하고, 필터는 픽셀 값을 바꿉니다. 둘이 서로 맞아야 플레이어가 파일을 의도대로 읽습니다.
작업 순서는 간단합니다. 시퀀스 패턴과 시작 번호를 확인하고, -framerate를 -i 앞에 둡니다. 다음으로 원본 전달 특성과 레인지를 확인해 zscale 변환과 출력 태그를 맞춥니다. H.264는 yuv420p, 편집용 ProRes는 422 HQ를 고른 뒤, 변환이 끝나면 ffprobe에서 코덱·픽셀 형식·레인지·색 태그를 확인하세요.
재생 앱마다 같은 파일이 다르게 보이면 인코딩 결과와 표시 환경을 분리해야 합니다. 유튜브 업로드 뒤 색이 바래 보일 때 감마와 Rec.709 태그를 가르는 방법에서 태그와 재생 감마를 확인하는 순서를 이어서 볼 수 있습니다.
공식 옵션은 아래 문서에서 확인할 수 있습니다. FFmpeg 빌드와 입력 색공간에 따라 실제 옵션 지원과 기본값은 달라질 수 있습니다.
vfx 잡학지식

댓글 0
첫 댓글을 남겨보세요.