18
2월
2009

웹사이트 최적화 : 8bit PNG 활용하기

21세기가 시작된 지 거의 10년이 다 되어가는 2009년에 이르러 네트워크와 인터넷은 놀라운 발전을 이뤄왔습니다. 웹브라우저 시장은 MS의 Internet Explorer가 독점하는 상황을 벗어나서, 지금은 파이어폭스, 사파리, 오페라, 크롬, … 기타 등등 수많은 브라우저가 서로 웹표준을 향해 경쟁하는 행복한(?) 시대가 되었지요.

하지만, 이런 상황에서도 웹브라우저가 공식적으로 지원하는 이미지 형식은 아직까지는 GIF, JPG, PNG 세 가지 뿐입니다. (BMP는 논외) 그 중에서 가장 돋보이는 포맷은 바로 PNG 인데요… 하지만, 이전에 작성했던 나를 미치게 하는 PNG 라는 포스트에서도 밝혔듯이.. IE6 의 점유율이 10% 이하로 떨어지지 않는 한, PNG의 혜택을 누리기에는 무리가 있습니다.

이런 상황에서 갑자기 8bit PNG 를 활용하자니… 이게 무슨 소린가 하시겠죠? 저도 그랬습니다. IE6 이 버티고 있는 한, png의 p자도 꺼내지 말아야 할 상황이 아닌가! 라고 반문했지요.

png의 포맷은 몇가지가 있습니다. color field에 따라 8bit, 24bit 로 나뉘는데요…

bit특징
8bitPallete PNG
이미지 내의 색상을 index화 하여 256 칼라를 사용할 수 있다는 GIF 와 비슷한 특성을 가지지만, 동일 이미지의 GIF 파일보다 크기가 작습니다. 그 외의 속성은 png와 같습니다. (Alpha Transparency, No Animated)
24bitTruecolor PNG
JPG와 같은 1670만 칼라를 지원하며, JPG와 달리 이미지의 손실(열화)이 없습니다. 그래서 이미지의 크기는 JPG보다 크지만, JPG의 최상퀄리티의 파일 크기에 비하면 오히려 작다고 할 수 있습니다. 그외에 역시 Alpha Transparency를 지원하며 애니메이션은 지원되지 않습니다.
ApngAnimated PNG
애니메이션이 지원되는 png입니다.

PNG 에 대한 자세한 원전은 다음 URL 에서 얻을 수 있습니다. https://tools.ietf.org/html/rfc2083

여기서 주목할 만한 것은 8bit PNG 입니다. GIF와 성질은 거의 비슷한데 GIF보다 파일 크기가 대체로 더 작습니다. 게다가 IE6 에서도 8bit PNG는 GIF와 비슷한 Transparency 를 지원하고 있습니다. 적어도 24bit PNG 처럼 투명 영역이 회색으로 보이는 문제가 없지요. 그래서 8bit PNG를 GIF를 대체하는 웹이미지로 사용할 수 있지 않을까 하는 것이 발상의 전환이죠.

다만 PNG 는 이전 포스트에서도 밝혔듯, 각각의 웹브라우저에서 실제 색상은 다르게 표현될 수 있습니다.

직접적인 원인은 PNG 이미지가 자체적으로 감마값을 가지고 있고, 이 값을 해석하는 브라우저가 상이한 결과를 내기 때문인데요…

PNG 파일의 구조는 8bit의 헤더(png이미지라는 것을 알리는 부분)와 여러 개의 chunk 라는 것으로 구성되어 있습니다. 디카로 사진 좀 찍어보신 분들은 아시겠지만 jpg파일도 이미지뷰어로 보면 각종 정보(카메라기종, 조리개, 셔터, WB 등)가 따로 저장되는 것을 볼 수 있는데요, PNG도 실제 이미지 데이터와 별도로 이러한 정보들이 하나의 조각(chunk)으로 저장된다고 보시면 비슷합니다. 색상의 불일치 문제를 일으키는 것은 바로 gAMA chunk 라는 것인데요, 이 값을 제대로 처리하는 웹브라우저가 있고, 이를 제대로 처리하지 못하는 웹브라우저가 있기 때문에 색상차이가 보이게 되는 것이지요.

결국, 모든 웹 브라우저에서 같게 표현되게 하려면 gAMA chunk 를 없애는 과정이 필요합니다. 사실 이 chunk를 제거하는 것은 근본적인 해결책은 아닐 겁니다. 근본적으로 해결하기 위해서는, png의 감마 값을 모든 브라우저에서 제대로 지원하고 JPG나 GIF도 이를 지원해야 한다는 뜻입니다. 그래서 조금 우회하여 png 도 다른 이미지와 마찬가지로 하향평준화 시킨다.. 라고 이해하는 것이 좋을 것 같습니다.

TweakPNG 이라는 프로그램으로 샘플 PNG 파일의 정보를 열어보았습니다.

뭔가 굉장히 많죠? IHDR이 png파일의 헤더이며 나머지 bKGD, sRGB, sBIT, pHYs … 뭔가 못알아볼 데이터들이 많지만 어쨌든 문제가 되는 chunk는 위에 표시한 gAMA chunk입니다. 여기서 gAMA값을 삭제하는 것 만으로 png파일을 웹에서 정상적으로 표기하게 하는 것이 가능합니다. 드디어 문제 해결! 24bit의 Truecolor PNG는 어쩔 수 없지만 GIF를 대신하여 8bit Palleted PNG 를 활용할 수 있습니다.

다만 이것에 만족하지 않고 웹사이트를 위한 이미지 최적화를 위해 PNG 파일 자체의 다이어트를 할 수 없을까 고민해볼 수도 있을 것 같네요. 다행히 방법은 있었습니다. gAMA값 외에도 이미지를 표기하는데에 굳이 필요없는 정보들을 삭제하고 데이터영역을 다시 압축하여 최적화시킬 수 있는 툴이 몇가지 존재합니다.

이것저것 테스트를 해보았는데요, 첫번째 제시된 pngcrush의 경우 windows의 명령프롬프트 위에서 실행해야 하는 불편함이 존재했지만 가장 확실할 것 같아 테스트해보았습니다. 실행 방법은 조금 복잡합니다. 간단히 프롬프트 상에서 pngcrush 라고 입력하면 여러가지 옵션이 나옵니다. 일단 레퍼런스 코드가 있어서 다음과 같이 입력해보았습니다.

C:>pngcrush -rem alla -brute -reduce sample.png sample1.png

위 명령을 실행하니 마지막에 나온 정보로 17.16%의 파일 사이즈를 줄일 수 있다고 나오는군요. 그래서 이렇게 나온 파일을 다시 TweakPNG로 열어본 결과 꼭 필요한 헤더와 푸터 chunk(IEND), 그리고 데이터 영역(IDAT)을 제외하고 모든 chunk 가 없어진 것을 확인할 수 있었습니다.

아래 상태표시줄을 확인하면 sample.png 파일의 크기가 13479byte에서 11166byte로 압축되었음을 알 수 있습니다. GIF 에 비해서 PNG 가 용량 면에서 효율적인데도, 덤으로 필요없는 정보를 다이어트 하여 더 크기를 줄일 수 있는 좋은 팁입니다.

이 과정은 조금 복잡하지만, 이 작업을 어느정도 자동화시키면 충분히 실무에도 활용 가능할 것으로 보고 있습니다. 저도 현재 진행중인 모 개편 프로젝트에서 8bit png의 활용과 함께 CSS 스프라이트 등의 최적화 방안을 적용하여 진행하고 있는 중입니다.

png파일이 있는 폴더 대상으로 pngcrush를 실행할 수 있는 방법은 다음과 같습니다.

C:>pngcrush -rem alla -brute -reduce -d "폴더명" *.png

위와 같이 하면 “폴더명”의 폴더가 생성이 되고, 그 안에 pngcrush가 처리한 png파일이 모두 저장이 됩니다.
-brute 옵션은 파일을 줄일 수 있는 방법을 모두 수행하는 방법이기 때문에 시간이 오래걸린다는 단점이 있지만 요즘의 컴퓨터 퍼포먼스가 좋기 때문에 웹 환경에서 생성되는 png 파일들이라면 많은 시간은 걸리지 않습니다. 실제로 저는 통검개편 작업에서 생성된 15개 정도의 png파일을 모두 돌리는데… 30초 정도 걸린 것 같습니다.

이 포스트는 NHN WSG(Web Standardization Guide) 블로그와 네이버의 개인 블로그에 함께 연재되고 있습니다.

5 Responses

  1. 마근엄 댓글:

    brute 옵션은 pngcrush 너무 많은 필터 조합을 시도하기 때문에 시간이 오래걸립니다. 최적의 필터 조합은 이미지에 따라 다소 다를 수 있지만 보통 3가지 중 하나가 됩니다. 제가 사용하는 옵션은 다음과 같습니다.

    pngcrush.exe -m 113 -m 121 -m 124 -d “PNG Crushed” *.png

  2. 무슨블로그야 댓글:

    여기 무슨 블로그이지…
    여기있는글 http://html.nhndesign.com/849 에서 나온글들인데
    왜여기에 출처 표시도 되지않은체 올라와있는지 ???

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

%d 블로거가 이것을 좋아합니다: