앞선 포스트에서 JPEG, PNG, 그리고 GIF까지 다양한 이미지 포맷에 대해 살펴봤다. 이 세 가지 포맷의 공통점은 나온 지 20~30년 정도 된 오래된 포맷이라는 점이다. 물론 오랫동안 사용된 만큼 이 포맷들을 지원하는 환경도 많고 널리 사용되고 있다는 장점도 있다. 하지만 과연 이게 최적일까?
당연히 그럴 리 없다.
현재 다방면에서 생산되는 이미지의 크기는 더 커지고 담기는 정보는 더 늘어났다. 웹 페이지 하나에 사용되는 리소스의 수도 엄청나졌다. 더군다나 더 뛰어난 압축 알고리즘, 더 효율적인 이미지 포맷도 나왔을 테다. 자신이 한 사람의 엔지니어라면 계속 비효율적인 JPEG, PNG만 사용할 것인가?
여기 JPEG의 lossy compression, PNG의 lossless compression, GIF의 animation을 전부 지원하면서 압축률은 더 좋은 이미지 포맷이 하나 있다.
WebP를 소개한다.
WebP는 2010년에 새로 제시된 이미지 포맷으로, 구글에서 개발하여 현재 무료로 배포하고 있는 이미지 포맷이다. Lossless와 lossy compression을 모두 지원하며 JPEG, PNG보다 높은 압축률을 보인다. 이미지 파일의 크기가 준다는 것은 자연스럽게 웹 페이지의 로드 부하를 줄여주는 효과로 이어진다.
이외에도 넓은 feature set을 보이니, 하나씩 살펴보자.
WebP 포맷을 검색해보면 항상 등장하는 대표적인 특징들이다.
JPEG 대비 25-34%, PNG 대비 26%, 그렇다면 GIF, APNG와 비교했을 때 압축률은 어떨까?
: Google 측 주장으로는 움직이는 GIF 이미지를 lossy WebP로 변환 시 64%, lossless WebP로 변환 시 19% 만큼 파일 크기가 줄어든다고 한다. 하지만 한 실험 결과에서는 GIF나 APNG 보다 WebP의 파일 크기가 크다! (출처: GIF vs APNG vs WebP)(왠지 압축 파라미터 설정의 차이 같기도 한데, 정확한 원인은 알 수 없다. ㅠㅠ)
WebP에서 사용된 compression 관련 내용은 다음 포스트에서 자세히 다루도록 한다.
WebP의 file format은 RIFF를 기반으로 작성되었다. 이는 chunk의 연속인데, chunk의 기본 구조는 아래와 같다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk FourCC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Payload |
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(* FourCC: Four Character Code)
첫 4바이트에 chunk type을 나타내는 4글자 ASCII 코드가 들어간다.
다음 4바이트 chunk size에 뒤 이을 chunk payload의 크기를 담는다.
마지막은 해당 chunk의 데이터를 담는 payload가 차지한다.
WebP file header: WebP 이미지 파일의 시작.
처음 WebP file header에서는 'R' 'I' 'F' 'F'의 FourCC와 'W' 'E' 'B' 'P'를 담은 payload가 들어간다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'R' | 'I' | 'F' | 'F' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| File Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'W' | 'E' | 'B' | 'P' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Simple file format: 여타 속성을 가지지 않고 순전히 이미지만 저장할 때.
Simple file format에서는 바로 압축 데이터가 등장한다. 이 때 compression 방식에 따라 VP8
chunk (lossy)나 VP8L
chunk (lossless)가 오게 될 것이다. 각 chunk에는 압축 과정에서 생성된 bitstream이 들어간다.
아래는 lossy compression의 VP8
chunk 예시다.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'V' | 'P' | '8' | ' ' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8 data size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| VP8 data |
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Extended file format: WebP에서 지원하는 다양한 확장 속성들을 사용할 때. (e.g., animation, Exif, XMP 등)
Extended file format에서는 다양한 속성의 chunk들이 이미지 데이터 앞뒤로 붙는다. 아래는 extended file format의 chunk 배치 순서다.
VP8X
: 아래 속성들의 사용 여부를 명시하고, canvas의 크기를 명시한다.ICCP
: Color profile 정보 저장.ANIM
: Animation의 global parameter들을 설정. (background color, loop count)ANIF
: Animation의 single frame 정보들을 담는다. (frame의 위치 및 크기, frame duration, frame data)ALPH
: Alpha channel 정보 저장.VP8
혹은 VP8L
chunk가 온다.EXIF
: Exif metadata 저장.XMP
: XMP metadata 저장.완성된 file format의 간략화된 예시들이다. 참고용으로 봐두자!
간단히 Lossless 압축만 된 이미지는 다음과 같다. (VP8X 헤더는 항상 들어가는 것 같다...)
RIFF/WEBP
+- VP8X (descriptions of features used)
+- VP8L (lossless bitstream)
ICC profile과 XMP metadata를 포함한 lossless 압축 이미지는 다음과 같다.
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP (metadata)
Exif metadata를 포함한 움직이는 이미지는 다음과 같다. (아니, VP8, VP8L이 따로 없다?)
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)
WebP에 대해 공부하면서 가장 의문스러웠던 점은 encoding/decoding time이다.
압축률이 높아지면 시간이 오래 걸리는 것은 꽤나 자연스러운 trade-off 같아 보이는데... 흠
만약 압축의 크기는 줄었지만 encoding/decoding 하는 데에 더 오래걸린다면 page load time에 이점이 없을 수도 있겠지..
물론 그렇다 하더라도 network, storage 부하를 줄인다는 장점은 없어지진 않는다. ㅎㅎ
뭐 어쨌든, WebP 포맷의 기본적인 내용과 file layout까지 이 글에서 다루었다.
사실 기본 내용과 file layout을 묶어두는 것이 맞는 지는 계속 의문이 든다. 안 넣으면 내용이 너무 부실해진다...
WebP의 압축 과정을 다른 포스트로 빼기로 결정하였으니, file layout도 이후에 분리하던지.. 고민해봐야겠다.