Base64를 ICO로 변환하는 방법
- Base64,
data:image/x-icon;base64,...URI, 또는<link rel="icon" href="data:...">태그 전체를 붙여넣으세요. - 상태 표시줄의 감지된 형식이 ICO인지 확인하고 미리보기를 보세요.
- 파일 다운로드를 누르세요. 이름은 기본적으로
decoded.ico이며, 웹사이트에 올릴 것이라면favicon으로 바꾸세요.
MIME 유형 필드에는 대부분의 서버와 data URI가 아이콘에 쓰는 image/x-icon이 표시됩니다.
여러 이미지를 담는 ICO 파일
PNG나 JPEG와 달리 ICO 파일은 작은 컨테이너입니다. 흔한 favicon.ico에는 16×16, 32×32, 48×48 버전이 들어 있고, Windows 애플리케이션 아이콘은 256×256을 더하는 경우가 많습니다. Windows는 작업 표시줄, 바탕 화면 바로 가기, 탐색기에 가장 알맞은 크기를 고르고, 브라우저는 탭에 쓸 크기를 고릅니다.
파일은 6바이트 헤더로 시작하고, 그다음 이미지마다 16바이트 디렉터리 항목이 하나씩 옵니다. 그래서 모든 ICO의 Base64는 바이트 00 00 01 00에 해당하는 AAABAA로 시작합니다. 크기가 세 개인 아이콘의 hex 덤프 표시 결과는 다음과 같습니다.
00000000 00 00 01 00 03 00 10 10 00 00 00 00 20 00 56 00 |............ .V.|
00000010 00 00 36 00 00 00 20 20 00 00 00 00 20 00 6b 00 |..6... .... .k.|
00000020 00 00 8c 00 00 00 30 30 00 00 00 00 20 00 8c 00 |......00.... ...|
00000030 00 00 f7 00 00 00 89 50 4e 47 0d 0a 1a 0a 00 00 |.......PNG......|
| 바이트 | 값 | 의미 |
|---|---|---|
00 00 | 0 | 예약됨 |
01 00 | 1 | 유형: 1 = 아이콘, 2 = 커서 |
03 00 | 3 | 이미지 개수 |
10 10 | 16, 16 | 첫 번째 이미지: 너비와 높이 (00이면 256) |
20 00 | 32 | 픽셀당 비트 수 |
56 00 00 00 | 86 | 이미지 데이터 크기(바이트) |
36 00 00 00 | 54 | 이미지 데이터 시작 위치 |
다음 두 항목은 32×32(20 20)와 48×48(30 30)을 설명합니다. 오프셋 54에서 첫 번째 이미지가 시작되며, 텍스트 열의 .PNG를 보면 PNG로 저장되어 있음을 알 수 있습니다.
안에 든 PNG 또는 BMP
ICO 안의 각 이미지는 완전한 PNG 파일이거나, 일반적인 BM 파일 헤더가 없는 비트맵으로 저장됩니다. 비트맵이라면 데이터가 28 00 00 00으로 시작하고, 색상 픽셀 뒤에 1비트 투명도 마스크가 오기 때문에 비트맵 헤더의 높이가 두 배로 적혀 있습니다. 256×256 같은 큰 이미지는 보통 PNG입니다. 그 크기의 비압축 32비트 비트맵은 256 KB가 넘기 때문입니다.
ICO 문자열은 보이는 아이콘보다 훨씬 긴 경우가 많습니다. 모든 크기가 들어 있고, 비트맵 항목은 압축되지 않기 때문입니다. 웹사이트라면 32×32 PNG 하나나 SVG 파비콘이 대개 훨씬 작습니다. 이를 인라인하는 방법은 파비콘을 Base64로에서 다룹니다.
코드에서 이미지 나열하고 추출하기
다음 Python 함수는 디렉터리를 읽고 각 이미지를 크기, 형식과 함께 돌려줍니다.
import base64, struct
def ico_entries(b64: str):
data = base64.b64decode(b64.split(",", 1)[-1])
reserved, kind, count = struct.unpack_from("<HHH", data, 0)
if reserved != 0 or kind not in (1, 2):
raise ValueError("not an ICO or CUR file")
for i in range(count):
w, h, colors, _, _, bpp, size, offset = struct.unpack_from("<BBBBHHII", data, 6 + 16 * i)
image = data[offset:offset + size]
fmt = "png" if image.startswith(b"\x89PNG") else "bmp"
yield {"size": f"{w or 256}x{h or 256}", "bpp": bpp, "bytes": size, "format": fmt, "data": image}
위 아이콘이라면 16x16, 32x32, 48x48이 나오며 모두 png입니다. PNG 항목의 entry["data"]를 .png 파일로 쓰면 그 크기의 독립된 이미지가 됩니다. 비트맵 항목은 다른 소프트웨어가 읽으려면 파일 헤더를 붙이고 마스크를 제거해야 하므로, 그런 경우에는 아이콘 편집기에서 ICO를 여세요. 디코딩은 Python에서 Base64에 더 자세히 있습니다.
아이콘이 열리지 않을 때
- “ICO이(가) 아니라 PNG(으)로 보입니다.” “파비콘” 문자열 중 상당수는 그냥 PNG입니다. 브라우저는 이름과 상관없이 PNG 파비콘을 받아들이지만, Windows 애플리케이션 리소스처럼 진짜 아이콘 파일이 필요한 소프트웨어는 이름만 바꾼 PNG를 받지 않습니다. .png(으)로 다운로드를 써서 PNG로 유지하세요.
- “이 브라우저는 ICO 이미지를 표시할 수 없습니다.” 브라우저가 파일 안의 어떤 이미지도 그리지 못했다는 뜻입니다. 대개 항목이 손상되었거나 잘렸거나 특이한 비트맵 형식을 쓰기 때문입니다. 다운로드는 여전히 정확한 데이터이므로, 아이콘 편집기에서 열어 어느 항목이 문제인지 확인하세요.
- 브라우저에서 파비콘이 바뀌지 않습니다. 브라우저는 파비콘을 별도의 캐시에 보관하므로 새 아이콘은 시크릿 창에서 확인하세요.
자주 묻는 질문
ICO 파일 안에 몇 가지 크기가 들어 있나요?
hex 덤프 표시를 열고 4–5번째 바이트를 읽으세요. 여기에 이미지 개수가 리틀 엔디언 숫자로 들어 있어 03 00이면 이미지 세 개입니다. 그다음 이미지마다 너비, 높이, 파일 내 위치가 담긴 16바이트 항목이 있습니다.
미리보기에 크기가 하나만 표시되는 이유는 무엇인가요?
브라우저가 아이콘에서 그릴 이미지를 하나 고르고, 크기 행은 그 이미지를 보고합니다. 다른 크기도 파일 안에 그대로 있으며 함께 저장됩니다.
ICO에서 PNG 하나만 추출할 수 있나요?
네, 그 항목이 PNG로 저장되어 있다면 가능합니다. 256×256 아이콘은 흔히 PNG로 저장됩니다. 그 바이트는 완전한 PNG 파일이며, 이 페이지의 Python 코드가 각각을 저장합니다.
Windows 커서 파일에도 쓸 수 있나요?
네. .cur 파일은 같은 컨테이너에서 유형만 1 대신 2를 쓰므로 Base64가 AAACAA로 시작합니다. CUR로 감지되어 .cur 확장자로 저장됩니다.