사이트 파비콘을 만들려고 변환 사이트에서 favicon.ico를 받았는데, 크기가 수백 KB나 되거나 반대로 브라우저 탭에서 흐릿하게 보이는 경우가 있습니다. PNG 하나면 될 것 같은데 왜 굳이 ICO라는 형식을 쓰는지도 헷갈립니다.
ICO는 그림 한 장이 아니라 크기가 다른 그림 여러 장을 담는 상자입니다. 보여 줄 곳의 크기에 맞는 그림을 골라 쓰라는 뜻이라, 무엇을 몇 장 넣느냐에 따라 선명도와 용량이 함께 달라집니다. 직접 만들어 보니 웹사이트용이라면 16·32·48 세 장을 PNG로 담는 것으로 충분했고, 이때 파일은 4.4KB였습니다.
아래 숫자는 512×512 투명 배경 로고 하나로 크기 조합을 바꿔 가며 ICO를 만들고, 파일 안의 목록을 직접 읽어 확인한 결과입니다. 측정 환경은 Ubuntu 24.04, 파이썬 3.13, Pillow 12.3.0입니다.
ICO 안에는 목차와 그림이 따로 들어 있습니다
ICO 파일의 맨 앞 6바이트는 '이 파일은 아이콘이고 그림이 몇 장 들어 있다'는 머리말입니다. 실제로 만든 파일의 첫 네 바이트는 00 00 01 00이었습니다. 그 뒤에 그림 한 장마다 16바이트짜리 목차 항목이 붙어 가로세로 크기, 색 깊이, 그림 데이터의 위치와 크기를 적어 두고, 그다음에 그림 데이터가 차례로 이어집니다.
브라우저나 운영체제는 이 목차를 읽고 지금 그릴 자리에 가장 맞는 크기 한 장만 꺼내 씁니다. 16픽셀 자리에 256픽셀 그림을 줄여 그리면 가는 선이 뭉개지기 때문에, 작은 크기는 따로 만들어 넣는 편이 선명합니다.

크기를 하나 늘릴 때마다 용량은 얼마나 늘까
16 한 장만 넣은 ICO는 673바이트였습니다. 32를 더하면 2.2KB, 48까지 넣으면 4.4KB가 됐습니다. 여기까지는 그림이 작아서 늘어나는 폭도 작습니다. 256을 더하는 순간 16.5KB로 커졌고, 24·64·128까지 7가지를 모두 넣으면 27.1KB였습니다.
Pillow로 저장한 ICO는 그림을 모두 PNG로 압축해 담았습니다. 목록을 열어 보니 256 한 장이 12.1KB로 파일의 4분의 3을 차지했습니다.
수백 KB짜리 ICO는 BMP로 담긴 경우입니다
ICO 안의 그림은 PNG뿐 아니라 압축하지 않은 BMP 방식으로도 담을 수 있습니다. 같은 네 가지 크기를 BMP로 담아 직접 만들어 보니 파일이 285.5KB가 됐습니다. 그중 256 한 장이 270,376바이트로 95%를 차지했습니다. 256×256 크기의 점 하나하나를 4바이트씩 그대로 적기 때문입니다.
256만 PNG로 바꾸고 나머지는 BMP로 두면 26.8KB로 줄었습니다. 받은 파비콘이 유난히 무겁다면 256 크기가 BMP로 들어 있을 가능성이 큽니다. 아래 코드로 목록을 열어 보면 바로 확인할 수 있습니다.
PNG 이름만 .ico로 바꾸면 어떻게 될까
32×32 PNG의 확장자만 .ico로 바꿔 Pillow로 열었더니 형식을 ICO가 아니라 PNG로 알아봤습니다. 파일 첫 바이트가 PNG의 표시인 89 50 4E 47 그대로였기 때문입니다. 확장자는 이름일 뿐이고 안의 내용은 바뀌지 않습니다.
브라우저 중에는 이런 파일도 내용을 보고 알아서 보여 주는 경우가 많지만, 진짜 ICO 구조를 기대하는 프로그램에서는 열리지 않을 수 있습니다. 크기도 한 가지뿐이라 다른 크기 자리에서는 늘리거나 줄여서 그려집니다. ICO가 필요한 곳에는 실제로 변환해서 넣는 편이 안전합니다.
어떤 크기를 넣으면 될까
| 쓰는 곳 | 넣을 크기 | 실측 용량(PNG로 담았을 때) |
| 웹사이트 favicon.ico | 16, 32, 48 | 4.4KB |
| 윈도우 프로그램이나 바로가기 아이콘 | 16, 32, 48, 256 | 16.5KB |
| 여러 화면 배율까지 고르게 대응 | 16, 24, 32, 48, 64, 128, 256 | 27.1KB |
일반적으로 16은 브라우저 탭, 32는 고해상도 화면의 탭과 작업 표시줄, 48은 탐색기의 중간 크기 아이콘, 256은 큰 아이콘 보기에 쓰입니다. 웹사이트라면 256까지 넣어도 화면에 쓰일 일이 거의 없어 용량만 네 배가 됩니다.
만들고 확인하는 코드
from PIL import Image
logo = Image.open("logo.png") # 정사각형, 512px 이상 권장
logo.save("favicon.ico", sizes=[(16, 16), (32, 32), (48, 48)])
ico = Image.open("favicon.ico")
print(ico.format, sorted(ico.info["sizes"]))
# ICO [(16, 16), (32, 32), (48, 48)]
원본이 정사각형이 아니면 찌그러져 들어가니, 먼저 정사각형으로 잘라 두는 편이 좋습니다. 16픽셀처럼 아주 작은 크기에서는 글자나 가는 선이 거의 보이지 않으므로, 로고에서 상징 부분만 남긴 단순한 그림을 따로 만들어 넣으면 훨씬 또렷해집니다.
ICO가 필요 없는 경우
아이폰 홈 화면에 추가할 때 쓰는 아이콘은 ICO가 아니라 180×180 PNG를 따로 지정합니다. 최신 브라우저는 PNG나 SVG 파비콘도 읽기 때문에, 요즘 사이트는 favicon.ico를 기본으로 두고 큰 크기는 PNG로 따로 연결하는 경우가 많습니다. ICO는 '어디서든 열리는 기본값'으로 작게 두는 것이 가장 효율적입니다.
함께 읽으면 좋은 글
'이미지' 카테고리의 다른 글
| 사진을 열었다 저장할 때마다 나빠진다는 말, 어디까지 사실일까 (0) | 2026.09.25 |
|---|---|
| 화면 캡처 PNG가 유독 무거울 때, 색 수를 줄여 절반으로 (0) | 2026.09.24 |
| 화면에서 쨍하던 초록이 인쇄물에서 칙칙해지는 이유 (0) | 2026.09.24 |
| 인쇄소에서 300DPI로 달라고 할 때, 사진 속성의 dpi를 고치면 되는 걸까? (0) | 2026.09.24 |
| 사진 수십 장을 한 장씩 WebP로 바꾸고 계신가요, 폴더째 한 번에 변환하는 법 (0) | 2026.09.24 |