마케팅·크롤러·협력사에서 넘어온 AVIF를, CMS·앱 스토어·레거시 파이프라인 때문에 PNG만 받는 하류로 붙여야 하는 경우가 늘었습니다. 본문은 디자이너·프론트가 같은 문장으로 말할 수 있는 2026 납품 매트릭스입니다: 어떤 디코더를 표준으로 할지, 8bit sRGB와 알파를 어떤 플래그로 고정할지, 원격 Mac mini M4에서 배치·실패 재시도·용량 임계를 디자인 수출 폴더 구조와 맞추는 방법까지 한 장에 묶었습니다. 포맷 혼용 전략은 WebP·AVIF vs PNG 체크리스트와 같이 읽으면 됩니다.
목차
도구 대비: 무엇을 기본 디코더로 할 것인가
| 도구 | 적합한 경우 | 주의 |
|---|---|---|
libavif avifdec |
AVIF→PNG를 재현 가능한 기본 경로로 고정할 때 | 빌드에 따라 YUV 범위·메타 처리 차이—워커마다 동일 Homebrew 핀 |
| ffmpeg | 이미 영상 파이프라인에 통합되어 있거나 단일 프레임 추출만 필요할 때 | -pix_fmt를 빼면 알파가 조용히 떨어질 수 있음—rgba 명시 |
ImageMagick 7 magick |
디코드 직후 색 공간·depth 정규화·PNG32 강제를 한 줄에 묶을 때 | delegate/libavif 버전이 이미지마다 다르면 CI와 로컬이 갈림 |
실무 권장: CI·원격 M4 모두 avifdec를 1순위로 두고, 실패 샘플만 ffmpeg로 폴백한 뒤 그 이유를 JSONL에 남깁니다. WebP 쪽 출구는 WebP→PNG 매트릭스와 동일한 게이트(stat·identify)를 공유하면 프론트가 한 스크립트로 검증합니다.
툴체인 선택: ffmpeg·libavif·ImageMagick을 어떻게 쪼개나
고정 원칙: 잡 시작 시 brew list --versions libavif(또는 패키지 매니페스트)·ffmpeg -version 첫 블록·magick -version을 로그에 붙이고, 입력 AVIF의 sha256과 함께 저장합니다. 원격 M4에서는 NVMe 스크래치에 .tmp를 쓰고 완료 후에만 최종 경로로 이동하세요.
기본 디코드 — libavif
avifdec 입력.avif /tmp/scratch/basename.png
품질 옵션은 인코더 쪽 이야기이고, 납품은 보통 무손실 디코드가 전제입니다. AVIF가 10bit/12bit이면 출력 PNG는 보통 8bit로 내리므로, 브리프가 “HDR 그대로”가 아니라면 8bit sRGB PNG로 계약을 적어 논쟁을 끕니다.
폴백 — ffmpeg(단 프레임)
ffmpeg -y -i 입력.avif -frames:v 1 -c:v png -pix_fmt rgba "/tmp/scratch/basename.png"
색 타입 강제 — ImageMagick
magick 입력.avif -colorspace sRGB -depth 8 PNG32:handoff.png
알파가 없는 자산이면 브리프 확인 후에만 PNG24로 내립니다. 무단 플래튼은 배치 실패로 처리합니다.
색·투명 처리 매개변수 표
| 항목 | 납품 계약(권장) | 검증 명령/기준 |
|---|---|---|
| 색 공간 | sRGB 고정(와이드는 별도 SKU) | magick identify -verbose 파일.png | egrep 'Colorspace|Gamma|Profile' — Display P3 임베드면 실패 처리 |
| 비트 심도 | 8bit/채널 PNG | Type가 TrueColorAlpha 등 기대와 일치; 16bit 필요 시 README에 예외 ID |
| 알파 | 직선 알파, 프리멀은 파일명·README에 명시 | #FFF / #0B0D12 배경 위 목검; 프린지 허용 픽셀 비율은 팀 합의치 |
| ICC | sRGB IEC61966-2.1 임베드 또는 전역 스트립+문서 한 줄 |
정책이 “스트립”인데 프로필이 붙어 있으면 실패 |
| 양자화(선택) | max_bytes 초과 시에만 허용 |
pngquant --quality=70-85 --speed 1 --skip-if-larger -f -o q.png in.png |
근손실 AVIF 원천은 PNG로 “복원”되지 않습니다. 품질 이슈는 상류 재수출이 우선이고, 본 매트릭스는 파이프라인 기계적 합격에 집중합니다. 대량 재압축 전략은 pngquant·zopflipng 배치 매트릭스와 품질대를 맞추세요.
배치 스크립트 단계와 실패 재시도
- 입력 스캔:
design-exports/avif/**/*.avif만 대상—PNG는 건너뜀. - 원자 쓰기: 동일 베이스명으로
.tmp.$$에 디코드 후mv로 승격. - 재시도: 디스크·네트워스 마운트 일시 오류는 지수 백오프 3회(
1s,4s,16s); 디코더 크래시는quarantine/원인코드/로 이동하고 슬랙·JSONL에sha256기록. - 병렬: M4는
xargs -P 4부터 시작해 메모리 피크를 보고 6~8로 조정—풀 HD 이상 연속 디코드는 RAM을 먹습니다.
MAX_RETRY=3
for avif in design-exports/avif/**/*.avif; do
base="$(basename "${avif%.avif}")"
out="handoff/png/${base}.png"
mkdir -p "$(dirname "$out")" handoff/quarantine
ok=0
for i in $(seq 1 "$MAX_RETRY"); do
tmp="${out}.tmp.$$"
if avifdec "$avif" "$tmp" 2>/dev/null && mv "$tmp" "$out"; then ok=1; break; fi
rm -f "$tmp"
sleep $((4 ** (i - 1)))
done
if [ "$ok" != 1 ]; then
echo "{\"file\":\"$avif\",\"stage\":\"avifdec\",\"ts\":$(date +%s)}" >> handoff/batch-fail.jsonl
mv "$avif" handoff/quarantine/decode-fail/ 2>/dev/null || true
fi
done
폴백 정책을 켤 때는 같은 루프 안에서 ffmpeg 한 번만 시도하고, 성공 시 로그 키 decoder_used를 ffmpeg로 표기합니다.
디자인 수출 디렉터리와 연동하는 검수 임계
디자이너가 Figma·Affinity에서 내는 트리(/avif 파생, /png 마스터)와 프론트의 public/assets를 1:1 매핑해 두면, 배치는 상대 경로만 바꾸는 설정 파일로 돌아갑니다.
| 검수 항목 | 임계 예시(SKU 조정) | 실패 시 조치 |
|---|---|---|
| 기하 | 스펙 WxH와 ±0 px | 재수출 요청—배치에서 임의 리사이즈 금지 |
max_bytes |
긴 변 ≤1600 기준 예: 린 ≤350KB, 일반 ≤800KB, 히어로 ≤1.6MB | pngquant 허용 대역으로 1회 시도 후에도 초과면 반려 |
| 바이트 검사 | 상한 800000 바이트 예시 | test "$(stat -f%z "$out")" -le 800000 실패 시 out-reject/ |
| 매니페스트 | 입력·출력 sha256 + 디코더 버전 | CDN 업로드 스크립트가 매니페스트 없으면 중단 |
magick identify -format "%wx%h %[colorspace] %[type]\n" handoff/png/아이콘.png
원격 노드 디스크 여유는 작업 전후로 15% 미만이면 잡 중단 같은 운영 수위를 두면, 대량 AVIF 디코드 중 OOM·부분 쓰기를 줄일 수 있습니다.
다음 단계: macpng.com에서 M4 배치 워커
macpng.com 홈, 구매·대여(패키지), 요금·노드, 도움말·SSH/VNC은 로그인 없이 열람할 수 있습니다. 야간 AVIF→PNG 스윕과 stat 게이트를 Apple Silicon 전용 원격 워커에 올리고, 동일 주제는 기술 인사이트의 WebP·AVIF·pngquant 글과 연결해 운영하세요.