품질보다 먼저 줄일 것은 픽셀
휴대폰이나 카메라로 찍은 사진은 대개 페이지에 들어갈 자리보다 훨씬 큽니다. 4000 x 3000 사진을 블로그에서 가로 1200픽셀로 보여 준다고 해 봅시다. 원본은 12,000,000픽셀인데 화면에 필요한 1200 x 900은 1,080,000픽셀, 딱 원본의 9%입니다. 브라우저가 실제 픽셀 2400 x 1800을 요구하는 2배율 화면에서도 4,320,000픽셀, 즉 36%면 충분합니다.
압축 전 상태에서 픽셀 하나는 채널당 8비트 기준 3바이트입니다. 원본은 36MB, 1200 x 900 버전은 3.24MB입니다. 압축기는 둘 다 줄여 주지만 출발점이 11배 작습니다. 눈에 띄는 손상 없이 11배를 줄여 주는 품질 슬라이더는 없습니다. 어차피 브라우저가 표시할 때 남는 픽셀을 버리는데, 그 축소는 내가 통제할 수 없는 간이 스케일러가 하기 때문입니다.
그래서 순서가 중요합니다. 실제로 표시할 가장 큰 크기(고해상도 화면용 2배 버전을 쓴다면 그것까지)로 먼저 줄이고, 그다음에 압축하세요. 1200만 화소 파일에 용량 제한을 맞추려고 품질만 내리면, 아무도 보지 못하는 픽셀은 그대로 달고 있으면서 흐리고 블록이 보이는 이미지가 됩니다.
| 버전 | 가로 x 세로 | 픽셀 수 | 원본 대비 | 압축 전 RGB 용량 |
|---|---|---|---|---|
| 카메라 원본 | 4000 x 3000 | 12,000,000 | 100% | 36.00MB |
| 가로 1200px 자리용 2배 | 2400 x 1800 | 4,320,000 | 36% | 12.96MB |
| 가로 1200px 자리용 1배 | 1200 x 900 | 1,080,000 | 9% | 3.24MB |
손실 압축과 무손실 압축
무손실 압축은 같은 픽셀 값을 더 적은 바이트로 저장합니다. 문서를 ZIP으로 묶는 것과 같습니다. PNG가 무손실이라서 디코딩하면 원래 값이 그대로 돌아옵니다. 스크린샷, 다이어그램, 단색 면과 선명한 경계가 많은 그림에는 무손실이 맞습니다. 같은 픽셀이 반복되는 구간이 잘 압축되기 때문입니다.
손실 압축은 사람이 알아채기 어려운 디테일을 골라 영구히 버립니다. JPEG, 손실 모드의 WebP, AVIF가 여기에 속합니다. 자연 이미지에는 완만한 그라데이션과 미세한 노이즈가 많고 눈이 그 손실을 잘 용인하므로 사진에 어울립니다. 사진을 무손실로 저장하면 보통 몇 배나 커지는 이유도 이것입니다. 카메라 JPEG를 PNG로 저장하면 화질이 좋아지지 않고 파일만 커집니다.
WebP와 AVIF는 두 방식을 모두 지원합니다. WebP에는 손실 모드(VP8 키 프레임 부호화 기반)와 무손실 모드가 있고 둘 다 투명도를 지원합니다. AVIF는 AV1 비디오 코덱의 정지 이미지 프로파일을 HEIF 컨테이너에 담은 형식이며 손실·무손실 모드와 알파 채널이 있습니다. 따라서 중요한 것은 어느 형식이 손실이냐가 아니라 저장할 때 어느 모드를 골랐느냐입니다.
품질 숫자가 실제로 조절하는 것
JPEG는 그림을 8 x 8 픽셀 블록으로 나누고, 블록마다 64개의 주파수 계수로 바꾼(이산 코사인 변환) 다음, 계수마다 양자화 테이블의 값으로 나눠 정수로 반올림합니다. 손실이 생기는 단계는 이 반올림 하나뿐입니다. 나누는 값이 크면 미세한 디테일에 해당하는 계수가 0이 되고, 0이 이어지는 구간은 저장 비용이 거의 들지 않습니다.
품질 값은 디테일을 몇 퍼센트 남기느냐가 아니라 이 테이블의 배율입니다. 전통적인 libjpeg 방식은 기본 테이블(JPEG 표준 Annex K의 휘도 테이블은 16, 11, 10, 16, 24, 40, 51, 61로 시작합니다)에, 품질이 50 미만이면 5000을 품질로 나눈 값, 50 이상이면 200에서 품질의 두 배를 뺀 값을 배율(%)로 곱합니다. 여러 품질에서 테이블 첫 행을 계산하면 다음과 같습니다.
품질 배율 휘도 테이블 첫 행
50 100 16, 11, 10, 16, 24, 40, 51, 61
75 50 8, 6, 5, 8, 12, 20, 26, 31
85 30 5, 3, 3, 5, 7, 12, 15, 18
95 10 2, 1, 1, 2, 2, 4, 5, 6
값 = floor((기본값 * 배율 + 50) / 100), 최솟값 175~85가 보통 적정선인 이유
품질을 95에서 85로 내리면 배율이 10에서 30으로 바뀌어 나누는 값이 모두 약 3배로 커지고(첫 항목은 2에서 5) 그만큼 계수가 거칠게 반올림됩니다. 절감되는 바이트의 대부분은 눈이 거의 구분하지 못하는 고주파 항에서 나옵니다. 85에서 75로 더 내리면 용량은 더 줄지만 글자나 대비가 강한 경계 주변에 블록 모양 경계와 모기 노이즈가 보이기 시작합니다. 대략 60 아래에서는 하늘 같은 그라데이션에 블록과 줄무늬가 대부분의 사진에서 눈에 띕니다. 90을 넘기면 눈에 띄는 이득 없이 파일만 빠르게 커집니다.
75~85는 관례이지 법칙이 아닙니다. 인코더마다 테이블과 품질 척도가 달라서 한 도구의 80이 다른 도구의 80과 같지 않고, WebP·AVIF의 품질 숫자도 JPEG 숫자와 비교할 수 없습니다. 믿을 만한 방법은 결과를 100% 배율로 열어 매끈한 면과 경계를 살피고, 손상이 보일 때까지 내렸다가 한 단계 되올리는 것입니다.
- 잎이나 직물처럼 질감이 많은 사진은 손상이 묻혀서 품질을 더 낮춰도 됩니다.
- 하늘, 피부, 스튜디오 배경처럼 매끈한 그라데이션은 줄무늬가 먼저 보이므로 높게 유지하세요.
- 사진 속 글자, 로고, UI는 윤곽 번짐이 일찍 드러나니 PNG나 다른 형식을 쓰세요.
크로마 서브샘플링
JPEG는 밝기(Y)와 두 색차 채널(Cb, Cr)을 따로 저장합니다. 사람의 눈은 밝기의 세부를 색의 세부보다 훨씬 정밀하게 구분하므로, 대부분의 인코더는 색 채널을 낮은 해상도로 저장합니다. 4:2:0 서브샘플링에서는 2 x 2 픽셀마다 밝기 샘플 4개에 Cb와 Cr 샘플이 하나씩이라 6개 값이 됩니다. 전해상도 4:4:4의 12개 값에 비하면 변환을 시작하기도 전에 샘플 수가 절반입니다.
사진에서는 차이가 잘 보이지 않습니다. 하지만 파란 바탕 위의 빨간 라벨, 가는 색선, 색이 있는 글자가 들어간 스크린샷에서는 경계 너머로 색이 번지고 글자가 뭉개져 보입니다. UI 스크린샷을 JPEG에 넣지 말아야 하는 이유 중 하나이고, 일부 인코더가 용량을 더 쓰는 4:4:4 옵션을 두는 이유이기도 합니다.
이미지 종류별 형식 선택
먼저 내용을 보고 고른 뒤 제출처가 그 형식을 받는지 확인하세요. 쓰는 도구에서 AVIF를 만들 수 없다면(마지막 절의 이 사이트 도구 설명 참고) 웹용 사진에는 WebP가 차선책입니다.
| 이미지 종류 | JPEG | PNG | WebP | AVIF | SVG |
|---|---|---|---|---|---|
| 사진 | 무난하고 어디서나 열림 | 부적합: 매우 큼 | 손실 모드로 JPEG보다 작음 | 대체로 가장 작음, 인코딩이 느림 | 해당 없음 |
| 스크린샷·UI | 부적합: 윤곽 번짐, 글자 뭉개짐 | 적합 | 무손실 모드에서 적합 | 가능, 글자 경계 확인 필요 | 해당 없음 |
| 로고·아이콘 | 부적합 | 래스터로는 적합 | 적합 | 가능 | 최적: 확대해도 손실 없음 |
| 투명도 필요 | 알파 채널 없음 | 지원 | 손실 모드에서도 지원 | 지원 | 지원 |
| 애니메이션 | 불가 | 불가(APNG는 별도 확장) | 지원 | 지원(AVIF 이미지 시퀀스) | SMIL이나 CSS로 가능 |
세대 손실: JPEG를 다시 저장하지 마세요
손실 파일을 열어 편집하고 다시 저장할 때마다 양자화가 또 일어납니다. 디코딩한 픽셀에는 지난번 저장의 반올림 오차가 이미 들어 있고, 새로 저장하면서 오차가 더해집니다. 블록 경계와 테이블이 정확히 맞으면 손상이 작을 수 있지만, 몇 픽셀만 잘라 내거나 크기나 품질을 바꾸면 맞지 않아 오차가 쌓입니다. 몇 번 저장하고 나면 블록이 점점 두드러지고 색이 변하는 모습으로 보입니다.
실무 규칙은 원본(카메라 원본이나 무손실 내보내기본) 하나를 마스터로 보관하고, 모든 배포용 파일을 그 마스터에서 한 번씩만 만드는 것입니다. 압축하고, 올리고, 내려받아 편집하고, 다시 압축하는 흐름은 피하세요. JPEG를 손실 설정으로 WebP나 AVIF로 바꾸는 것도 두 번째 손실 세대입니다. 용량은 여전히 줄겠지만 원본에서 시작하는 편이 낫습니다.
picture, srcset, sizes로 최신 형식 제공하기
picture 요소는 브라우저가 디코딩할 수 있는 첫 번째 source를 고르게 하고, 나머지 모든 경우에는 일반 img가 대체 역할을 합니다. 각 source의 srcset에는 같은 그림을 w 단위로 여러 너비에 맞춰 나열하고, sizes는 레이아웃에서 그 이미지가 얼마나 넓게 그려질지 알려서 CSS가 적용되기 전에도 브라우저가 파일을 고를 수 있게 합니다. AVIF, WebP, 대체 이미지 순서로 적으세요.
아래 예시는 콘텐츠 영역이 휴대폰에서는 화면 너비 전체이고 최대 CSS 1200픽셀이라고 가정합니다. 높이는 4:3 비율을 따릅니다(480이면 360, 800이면 600, 1200이면 900). width와 height 속성은 이미지를 불러오는 동안 자리를 확보해 레이아웃 이동을 막아 줍니다.
<picture>
<source type="image/avif"
srcset="photo-480.avif 480w, photo-800.avif 800w, photo-1200.avif 1200w, photo-2400.avif 2400w"
sizes="(min-width: 1200px) 1200px, 100vw">
<source type="image/webp"
srcset="photo-480.webp 480w, photo-800.webp 800w, photo-1200.webp 1200w, photo-2400.webp 2400w"
sizes="(min-width: 1200px) 1200px, 100vw">
<img src="photo-1200.jpg"
srcset="photo-480.jpg 480w, photo-800.jpg 800w, photo-1200.jpg 1200w, photo-2400.jpg 2400w"
sizes="(min-width: 1200px) 1200px, 100vw"
width="1200" height="900" alt="사진 설명" loading="lazy" decoding="async">
</picture>이 사이트 도구가 실제로 하는 일
이미지 압축 도구와 이미지 크기 조절 도구는 모두 브라우저 안의 캔버스에서 동작합니다. 파일을 디코딩해 출력 크기로 그린 뒤 다시 인코딩합니다. 업로드는 없고 원본도 덮어쓰지 않습니다. 둘 다 PNG, JPEG, WebP를 받아 PNG, JPEG, WebP로 저장합니다. AVIF, SVG, GIF는 만들지 않습니다. AVIF가 필요하면 libavif의 avifenc 같은 전용 인코더나 빌드 환경의 이미지 라이브러리를 쓰세요.
압축 도구에는 두 가지 모드가 있습니다. 목표 용량 모드는 5~5,000KB(1KB는 1,024바이트) 사이의 제한을 받아 가장 낮은 품질부터 시도한 뒤, 품질 0.1~1.0 범위에서 9단계 이분 탐색으로 제한에 들어오는 가장 좋은 파일을 찾습니다. 가장 낮은 품질도 크면 배율을 단계적으로 낮추되 원본의 10% 아래로는 가지 않고, 제한을 넘는 파일을 내놓는 대신 오류를 알립니다. 크기 조정을 허용했고 이미지가 브라우저 캔버스 한도를 넘으면 줄어든 크기에서 탐색을 시작합니다. 품질 모드는 40~95 슬라이더(기본 82)와 WebP·JPEG·PNG 출력을 제공하며 PNG를 고르면 슬라이더는 무시됩니다. 결과가 원본보다 작지 않으면 다운로드를 비활성화하고 원본을 유지하라고 안내합니다. 브라우저가 선택한 WebP 대신 PNG를 반환하면 지원하지 않는 형식이라는 오류를 보여 줍니다. 20MB를 넘는 파일은 받지 않습니다.
크기 조절 도구는 정확한 픽셀 값이나 1~500% 비율을 받고, 가로세로 비율 잠금, JPEG·WebP용 품질 슬라이더(10~100, 기본 90)가 있으며 출력은 한 변 8192픽셀, 전체 64메가픽셀까지로 제한됩니다. 캔버스의 고품질 보간 설정으로 부드럽게 줄입니다. 두 도구 모두 이미지를 다시 그리므로 내장 EXIF 메타데이터와 원본 색상 프로필은 결과에 이어지지 않습니다. 색은 sRGB로 변환되며 Chrome의 JPEG 인코더는 일반 sRGB ICC 프로필을 붙일 수 있습니다. JPEG로 바꾸면 투명 영역이 흰색이 됩니다. 특정 크기와 용량 제한이 모두 필요하다면 먼저 크기를 줄이고 그다음에 압축하세요.
- 업로드 양식의 용량 제한에 맞출 때: 압축 도구, 목표 용량 모드, JPEG 또는 WebP.
- 자리에 맞는 정확한 픽셀 크기나 @2x 한 쌍이 필요할 때: 크기 조절 도구의 픽셀 모드로 줄인 뒤 압축.
- AVIF가 필요할 때: 전용 인코더로 만들고, 이 도구들은 JPEG·WebP 대체본에 쓰세요.