favicon.ico에는 어떤 크기를 담아야 하나요?
16, 32, 48px 이 셋이 브라우저 탭, Alt-Tab 전환기, 바탕 화면을 감당하며 1995년부터 권장되어 온 조합입니다. 256은 아이콘이 큰 아이콘 보기에서도 버텨야 할 때만 더하십시오.
PNG, JPG, SVG, WebP를 다중 크기 .ico로 온라인 변환합니다. 16·32·48px를 한 파일에 담고 알파 채널을 보존하며, 내장 PNG와 비압축 BMP 용량을 함께 표시합니다.
이미지를 여기에 놓거나 클릭하여 선택
PNG, JPG, SVG, WebP, GIF, BMP · 최대 10MB
둘 다 .ico 안에서 유효합니다. PNG는 Vista 이후의 Windows와 현재 모든 브라우저가 읽습니다. 한편 20개 사이트를 표본으로 살펴 찾아낸 진짜 ICO 파일 14개 가운데 13개는 비압축 BMP였는데, ImageMagick이 기본적으로 그쪽으로 변환하기 때문입니다.
<link rel="icon" href="/favicon.ico" sizes="16x16 32x32 48x48"> <link rel="icon" type="image/svg+xml" href="/icon.svg"> <link rel="apple-touch-icon" href="/apple-touch-icon.png">
.ico 파일을 여기에 놓거나 클릭하여 선택
파일 안의 모든 크기를 따로따로 나열합니다
| 오프셋 | 바이트 | 필드 | 값 |
|---|---|---|---|
| 0 | 2 | idReserved | 0 |
| 2 | 2 | idType | 1 |
| 4 | 2 | idCount | 3 |
| 6 | 1 | bWidth[0] | 16 → 16 |
| 7 | 1 | bHeight[0] | 16 → 16 |
| 8 | 1 | bColorCount[0] | 0 |
| 9 | 1 | bReserved[0] | 0 |
| 10 | 2 | wPlanes[0] | 1 |
| 12 | 2 | wBitCount[0] | 32 |
| 14 | 4 | dwBytesInRes[0] | 248 |
| 18 | 4 | dwImageOffset[0] | 54 |
| 22 | 1 | bWidth[1] | 32 → 32 |
| 23 | 1 | bHeight[1] | 32 → 32 |
| 24 | 1 | bColorCount[1] | 0 |
| 25 | 1 | bReserved[1] | 0 |
| 26 | 2 | wPlanes[1] | 1 |
| 28 | 2 | wBitCount[1] | 32 |
| 30 | 4 | dwBytesInRes[1] | 720 |
| 34 | 4 | dwImageOffset[1] | 302 |
| 38 | 1 | bWidth[2] | 48 → 48 |
| 39 | 1 | bHeight[2] | 48 → 48 |
| 40 | 1 | bColorCount[2] | 0 |
| 41 | 1 | bReserved[2] | 0 |
| 42 | 2 | wPlanes[2] | 1 |
| 44 | 2 | wBitCount[2] | 32 |
| 46 | 4 | dwBytesInRes[2] | 1464 |
| 50 | 4 | dwImageOffset[2] | 1022 |
Go Tools 변환 도구를 개발하는 개발자들이 작성하고 검토했습니다. 여기 설명한 컨테이너 구조, 바이트 수, 실패 양상은 남이 이 포맷을 요약한 글이 아니라 문서로 남긴 도메인 검토에서 나온 것입니다.
16, 32, 48px 이 셋이 브라우저 탭, Alt-Tab 전환기, 바탕 화면을 감당하며 1995년부터 권장되어 온 조합입니다. 256은 아이콘이 큰 아이콘 보기에서도 버텨야 할 때만 더하십시오.
네, 바로 그러라고 있는 포맷입니다 이 포맷 자체가 컨테이너입니다. 6바이트 헤더, 이미지마다 16바이트 디렉터리 엔트리, 그다음이 이미지입니다. 각각이 따로 그린 그림이며, 좋은 아이콘이 16px에서도 또렷한 이유가 여기 있습니다.
제대로 하면 사라지지 않습니다 .ico 안에 이미지를 저장하는 두 방식 모두 8비트 알파 채널을 온전히 담습니다. 투명도는 도구가 알파 바이트를 비워 두거나, 오래된 소프트웨어가 대신 읽는 1비트 마스크를 빠뜨릴 때만 사라집니다.
비압축 264KB, PNG로는 몇 KB 비압축 256px 레이어는 정확히 270,376바이트입니다. 헤더 40바이트, 픽셀 262,144바이트, 마스크 8,192바이트이며 그림이 무엇이든 같습니다. 같은 레이어를 PNG로 저장하면 대개 몇 KB면 됩니다.
.ico는 이미지 포맷이라기보다 이미지를 모아 둔 작은 아카이브에 가깝습니다. 안에 그림이 몇 장 들었는지 알려 주는 6바이트 헤더로 시작해, 그림 한 장마다 너비·높이·바이트 수·파일 내 위치를 담은 16바이트 디렉터리 엔트리가 이어지고, 그다음에 그림 데이터 자체가 옵니다. 각 그림은 두 가지 방식 중 하나로 저장됩니다. 완전한 PNG 파일을 통째로 내장하거나, 1비트 투명 마스크를 아래에 덧붙인 비압축 Windows 비트맵으로 담는 것입니다.
이 설계 덕분에 파비콘 하나가 브라우저 탭에서는 16px로, 파일 탐색기에서는 48px로 모두 선명하게 보입니다. 한 이미지를 늘였다 줄였다 하는 것이 아니라 크기마다 따로 다듬어 그린 별개의 그림이기 때문입니다. 같은 설계에서 몇 가지 뜻밖의 성질도 나옵니다. 변의 길이가 1바이트에 저장되므로 256은 0으로 적히고 512는 아예 적을 수 없습니다. 또 디렉터리가 엔트리마다 크기를 기록하는데 이미지 데이터도 같은 크기를 기록하므로 둘이 어긋날 수 있고, 소프트웨어마다 믿는 쪽이 다릅니다.
$ file favicon.ico
favicon.ico: MS Windows icon resource - 3 icons, 16x16, 32 bits/pixel, 32x32, 32 bits/pixel
$ python3 -c "from PIL import Image; print(sorted(Image.open('favicon.ico').ico.sizes()))"
[(16, 16), (32, 32), (48, 48)] 기본은 16, 32, 48px이며 최대 256px까지 담습니다. 각 크기는 위 레이어에서 줄이는 대신 원본에서 전체 품질로 따로 그려지므로, 작은 크기가 큰 크기의 뭉개짐을 물려받지 않습니다.
컨테이너가 허용하는 두 페이로드 형식은 장단점이 크게 다른데도, 자기가 어느 쪽을 쓰는지 밝히는 변환기는 거의 없습니다. 여기서는 스위치로 제공하고 각각의 결과 용량까지 표시하므로 짐작이 아니라 숫자로 결정할 수 있습니다.
알파 채널을 온전히 기록하고, 오래된 소프트웨어가 대신 읽는 1비트 마스크도 비워 두지 않고 알파에서 유도합니다. 그 마스크를 비워 두는 것이 마스크만 읽는 환경에서 투명 아이콘이 검은 사각형으로 변하는 원인입니다.
반대 방향 탭은 .ico 안의 모든 이미지를 실제 크기, 저장 형식, 비트 심도, 투명도의 출처와 함께 나열합니다. 잘 알려진 몇몇 파비콘이 여전히 쓰는 팔레트 기반 비트맵도 포함됩니다. 브라우저는 그중 한 장만 보여 줍니다.
디렉터리가 주장하는 크기와 이미지 데이터가 맞지 않으면 표시합니다. Firefox가 버리는 내장 PNG도 함께 표시합니다. Firefox의 ICO 디코더는 8비트 RGB나 RGBA만 받으므로 팔레트나 그레이스케일 레이어는 거기서만 사라지고, 다른 브라우저에서는 모두 정상적으로 보입니다. 둘 다 아이콘이 한 프로그램에서는 나오고 다른 프로그램에서는 빈칸으로 뜨는 흔한 원인인데, 어느 쪽이든 알려 주는 변환기는 달리 없습니다.
읽기, 크기 조정, 포장이 모두 이 페이지 안에서 이루어집니다. 파일이 서버에 닿지 않으므로 나중에 지울 것도, 기다릴 대기열도 없습니다.
magick in.png -define icon:auto-resize=48,32,16 favicon.ico 가장 흔한 답이자 그토록 많은 파비콘이 비압축인 이유입니다. 256px를 제외한 모든 레이어를 포장 전에 비트맵으로 변환하므로 세 크기가 수백 바이트가 아니라 15KB 안팎으로 나옵니다. 크기는 큰 것부터 기록됩니다.
img.save('favicon.ico', sizes=[(16,16),(32,32),(48,48)]) PNG를 내장하므로 같은 세 크기가 대략 10분의 1 공간에 들어갑니다. Pillow는 ICO 읽기도 잘합니다. Image.open(f).ico.sizes()가 안에 무엇이 있는지 알려 주어 남의 파일을 점검할 때 편리합니다.
npx png-to-ico icon.png > favicon.ico PNG 하나 이상을 받아 PNG 페이로드로 포장하는 단일 목적 CLI입니다. 빌드 스크립트에 넣기 편하지만 크기 조정은 대신해 주지 않으므로 각 크기를 개별 파일로 직접 준비해야 합니다.
sharp(input).resize(32).png() 개별 PNG를 뽑는 데는 훌륭하지만 ICO 컨테이너는 쓰지 못하므로 보통 위의 포장 도구 중 하나와 함께 씁니다. 빌드 파이프라인이 이미 sharp로 표준화되어 있을 때 흔히 혼란이 생기는 지점입니다.
github.com/Kodeworks/golang-image-ico image.Image에서 이미지 한 장짜리 ICO를 기록합니다. 크기 하나짜리 파비콘에는 충분하지만, 여러 크기를 한 컨테이너에 담으려면 디렉터리를 직접 써야 하며 대략 서른 줄 분량입니다.
.rc 리소스 스크립트, rc.exe 애플리케이션 아이콘을 뽑는 일반적인 방법입니다. 컴파일러가 .ico를 실행 파일의 리소스 섹션에 내장하며, 그 안의 컨테이너는 웹 파비콘과 정확히 같은 형식입니다.
.ico 이미지의 각 레이어를 아이콘 크기 하나로 내보내고, 압축 PNG를 포함해 레이어별로 비트 심도를 고를 수 있게 합니다. 이 선택을 조용히 대신 결정하지 않고 드러내 보여 주는 몇 안 되는 그래픽 도구입니다.
sips -s format ico in.png --out favicon.ico macOS에도 ICO 쓰기 기능은 실제로 있습니다. sips --formats는 com.microsoft.ico를 쓰기 가능으로 표시하며, 위 명령은 여기서 유효한 파일을 만들어 냈습니다. 못 하는 것은 여러 크기를 한 파일에 담는 일로, 출력은 48×48 한 장뿐이었습니다. 검색 결과가 대신 권하는 iconutil은 Apple 고유 컨테이너인 .icns를 만들며, 이는 Windows와 브라우저가 읽지 못합니다.
$ xxd -l 38 favicon.ico
00000000: 0000 0100 0300 1010 0000 0100 2000 e903 ............ ... 00000010: 0000 3600 0000 2020 0000 0100 2000 6c05 ..6... .... .l. 00000020: 0000 1f04 0000 ......
0000은 예약 필드, 0100은 타입 1(커서가 아니라 아이콘), 0300은 이미지가 세 개라는 뜻입니다. 이어지는 것이 첫 번째 16바이트 디렉터리 엔트리입니다. 10 10은 16×16, 00은 색상 수, 00은 예약, 0100은 평면 하나, 2000은 픽셀당 32비트, e903 0000은 페이로드가 1,001바이트라는 뜻이며 그 위치는 3600 0000 = 54입니다. 54는 정확히 6 + 3 × 16, 즉 디렉터리의 끝입니다. 한 바이트로 저장되는 크기를 빼면 여러 바이트로 된 값은 모두 리틀 엔디언입니다.
bWidth = 0x00 bHeight = 0x00
256 × 256
디렉터리는 각 변을 1바이트로만 담기 때문에 표현할 수 있는 최댓값이 255이며, 0이 256을 뜻하도록 정의되어 있습니다. 이 페이지 어디에도 512px가 없는 이유도 같습니다. 512를 담을 수 있는 바이트가 아예 없습니다. 그런데도 512px를 제공하는 온라인 변환기가 적지 않고, 이들은 자기 뒤에 오는 이미지를 설명하지 못하는 디렉터리 엔트리를 씁니다.
16 + 32 + 48 px, PNG payloads 16 + 32 + 48 px, uncompressed BMP payloads
389 bytes 15,086 bytes
비압축 페이로드의 비용은 40 + 너비 × 높이 × 4바이트에 1비트 마스크를 더한 값이라, 크기는 치수에만 달려 있고 그림 내용과는 전혀 무관합니다. 서로 아무 관련 없는 세 사이트가 길이가 바이트 단위로 똑같은 파비콘을 배포할 수 있는 이유입니다.
$ magick logo.png -define icon:auto-resize=48,32,16 favicon.ico $ file favicon.ico
favicon.ico: MS Windows icon resource - 3 icons, 48x48, 32 bits/pixel, 32x32, 32 bits/pixel
ImageMagick은 256px를 제외한 모든 레이어를 비압축 비트맵으로 변환한 뒤 포장하므로, 결과물이 수백 바이트가 아니라 15KB 안팎이 됩니다. Pillow는 반대로 PNG를 내장합니다: Image.open('logo.png').save('favicon.ico', sizes=[(16,16),(32,32),(48,48)]).
$ magick favicon.ico favicon-%d.png
favicon-0.png 48×48 favicon-1.png 32×32 favicon-2.png 16×16
브라우저가 대신해 줄 수 있는 일이 아닙니다. 다중 크기 .ico를 <img> 태그에 넘기면 크기가 어떤 순서로 들어 있든 돌아오는 이미지는 딱 하나, 가장 큰 것뿐입니다. 파일 안에 실제로 무엇이 들었는지 나열하려면 컨테이너를 직접 파싱해야 하고, 그것이 ICO → PNG 탭이 하는 일입니다.
PNG, JPG, SVG, WebP, GIF, BMP를 모두 받으며 최대 10MB까지 허용됩니다. 파일은 브라우저 밖으로 나가지 않습니다. File API로 읽어 들이고 모든 픽셀은 로컬 canvas에 그려집니다.
처음에는 16, 32, 48px가 선택되어 있습니다. 큰 아이콘 보기나 고해상도 데스크톱에서도 버텨야 한다면 64, 128, 256을 추가하십시오. 원본이 선택한 최대 크기보다 작으면 조용히 확대하지 않고 페이지가 그 사실을 알려 줍니다.
기본값은 PNG입니다. 용량이 한 자릿수 배 작고 현재 모든 브라우저와 Vista 이후의 모든 Windows가 읽을 수 있기 때문입니다. 실제로 배포되는 파비콘 대부분의 형태를 원한다면 비압축 BMP로 전환하십시오. 두 용량은 나란히 표시됩니다.
.ico를 저장하고, 마크업이 필요하면 link 태그 복사 버튼을 사용하십시오. 루트의 /favicon.ico 경로는 여전히 대비책으로 동작하지만, 브라우저가 먼저 시도하도록 명시된 경로는 link 요소입니다.
256px 이미지에 해당하는 디렉터리 바이트는 반드시 0이어야 합니다. 255로 적는 것은 무해한 1 차이처럼 보이지만, 일부 브라우저가 조용히 그리기를 거부하는 파일을 낳습니다.
bWidth = 0xFF bHeight = 0xFF ; 256을 뜻하려던 "255"
bWidth = 0x00 bHeight = 0x00 ; 0이 256을 뜻하도록 정의됨
디렉터리 엔트리는 16×16이라 하는데 페이로드가 실제로는 32×32이면 디코더가 갈립니다. 어떤 디코더는 디렉터리를 믿고 아무것도 그리지 않고, 어떤 디코더는 페이로드를 믿고 멀쩡히 렌더링합니다. 그러면 그 파일은 한 컴퓨터에서는 잘 되고 다른 컴퓨터에서는 보이지 않습니다.
entry: 16×16 payload IHDR: 32×32
entry: 32×32 payload IHDR: 32×32
비압축 레이어 안에서 높이는 색상 데이터와 마스크를 함께 포함합니다. 그냥 높이를 적으면 어떤 디코더에서는 빈 화면으로, 어떤 디코더에서는 이미지의 아래 절반으로 보이는 파일이 되며 양쪽 다 오류를 내지 않습니다.
biHeight = 32 ; 32px 이미지의 경우
biHeight = 64 ; 2 × 32, 색상 데이터와 마스크
어떤 도구는 마스크만 채우고 알파 바이트를 전부 0으로 남깁니다. 한 디코더는 이를 완전히 투명한 이미지로 읽어 아이콘이 사라지고, 다른 디코더는 마스크로 되돌아가 제대로 보여 줍니다. 둘을 일관되게 모두 기록하면 이 논쟁 자체를 피할 수 있습니다.
alpha bytes: all 0x00 mask: all 0x00
alpha bytes: real values mask: set where alpha < 128
SVG 내부의 외부 참조는 래스터화할 때 차단되며 그 사실을 아무도 알려 주지 않습니다. 오류도 나지 않고 canvas도 계속 읽을 수 있습니다. 깨진 이미지 자리 표시자만 아이콘에 그대로 구워집니다. 변환하기 전에 도안을 인라인으로 넣으십시오.
<image href="https://cdn.example.com/logo.png"/>
<image href="data:image/png;base64,iVBORw0KGgo…"/>
00 00, 아이콘을 뜻하는 01 00(02 00은 커서 파일), 그리고 2바이트 개수입니다. 각 디렉터리 엔트리는 너비, 높이, 팔레트 크기, 예약 바이트가 각각 1바이트씩이고, 이어서 2바이트 평면 수와 비트 심도, 마지막으로 페이로드의 길이와 위치를 담은 4바이트 필드 두 개가 옵니다. 여러 바이트를 쓰는 값은 전부 리틀 엔디언입니다.ceil(너비 ÷ 32) × 4바이트를 더합니다. 그래서 16px 레이어는 1,128바이트, 48px는 9,640바이트, 256px는 270,376바이트이며 그림이 무엇이든 달라지지 않습니다. 이 고정 비용 때문에 아무 관련 없는 세 사이트가 길이가 똑같은 파비콘을 배포할 수 있고, 이 페이지가 256px 레이어를 페이로드가 PNG일 때만 제공하는 이유이기도 합니다.image/vnd.microsoft.icon은 2003년 9월 IANA에 등록되었고, 그 등록이 인용하는 참고 문헌은 1995년 마이크로소프트 글 「Icons in Win32」입니다. ICO 명세로 널리 인용되는 RFC 2361은 사실 제목이 「WAVE and AVI Codec Registries」이며 이미지에 대해서는 한마디도 하지 않습니다.magick logo.png -define icon:auto-resize=48,32,16 favicon.ico입니다. 변환 도구
2진수, 16진수, 10진수, 8진수 및 임의 진법(2-36)을 즉시 변환합니다. 온라인에서 무료로 사용할 수 있으며 모든 처리는 브라우저에서 이루어집니다.
변환 도구
부호 있는 정수를 넣으면 부호-절대값, 1의 보수, 2의 보수, 오프셋 바이너리를 4~64비트로 한 번에 계산합니다. 비트열이나 16진수로 역방향 조회도 지원합니다.
변환 도구
리눅스 파일 권한을 8진수(755, 644)와 rwx 기호로 변환하는 온라인 chmod 계산기. 명령 생성과 777 위험 경고까지 브라우저에서 바로 처리합니다.
변환 도구
HEX, RGB, HSL, OKLCH, OKLAB, CMYK 등 9가지 색상 형식을 브라우저에서 즉시 변환합니다. 무료 온라인 도구, 가입 불필요.
변환 도구
HEX 색상을 CMYK로 변환합니다. 인쇄 시안용 sRGB 기반 근사. 무료 온라인 도구, 색상은 페이지를 벗어나지 않습니다.
변환 도구
HEX 색상을 HSL로 변환합니다. 3자리, 6자리, 알파 포함 8자리 모두 지원. 무료 온라인 도구, 즉시 변환.