如何将 Base64 转换为 ICO
- 粘贴 Base64、
data:image/x-icon;base64,...URI 或整个<link rel="icon" href="data:...">标签。 - 确认状态行中的 检测结果 为 ICO,并查看预览。
- 点击 下载文件。默认文件名是
decoded.ico;如果要用在网站上,请改名为favicon。
MIME 类型 字段显示 image/x-icon,这是大多数服务器和 data URI 为图标使用的类型。
ICO 文件包含多张图片
与 PNG 或 JPEG 不同,ICO 文件是一个小容器。典型的 favicon.ico 包含 16×16、32×32 和 48×48 三个版本,Windows 应用程序图标通常还会加上 256×256。Windows 会为任务栏、桌面快捷方式或资源管理器挑选最合适的尺寸;浏览器则为标签页挑选一个。
文件以 6 字节的文件头开始,然后每张图片对应一个 16 字节的目录条目。因此每个 ICO 的 Base64 都以 AAABAA 开头,也就是字节 00 00 01 00。下面是一个包含三种尺寸的图标的 显示 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 favicon 通常小得多。如何内联它们,见 Favicon 转 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 有更多关于解码的内容。
图标打不开时
- 提示“这看起来是 PNG,而不是ICO”。 很多“favicon”字符串其实就是普通的 PNG。浏览器接受任何名称的 PNG favicon,但需要真正图标文件的软件,例如 Windows 应用程序资源,不接受改了名的 PNG。用 下载为 .png 保存,保持 PNG 格式即可。
- 提示“你的浏览器无法显示 ICO 图片”。 浏览器无法绘制文件中的任何一张图片,通常是因为某个条目已损坏、被截断,或使用了不常见的位图格式。下载的仍然是完全相同的数据;用图标编辑器打开,看看是哪个条目出了问题。
- 浏览器中的 favicon 没有变化。 浏览器会把 favicon 单独缓存,所以请在无痕窗口中检查新图标。
常见问题
我的 ICO 文件里有几种尺寸?
打开 显示 hex 转储,读取第 4 和第 5 个字节:它们以小端序保存图片数量,所以 03 00 表示三张图片。之后每张图片有一个 16 字节的条目,记录宽度、高度及其在文件中的位置。
为什么预览只显示一种尺寸?
浏览器会从图标中挑一张图片来绘制,尺寸一行报告的就是这一张。其他尺寸仍在文件中,会随文件一起保存。
能从 ICO 中提取单独的 PNG 吗?
可以,前提是该条目以 PNG 存储,256×256 的图标通常如此。它的字节就是一个完整的 PNG 文件;本页的 Python 代码片段可以逐个保存。
这个工具能处理 Windows 光标文件吗?
能。.cur 文件使用相同的容器,只是类型为 2 而不是 1,所以它的 Base64 以 AAACAA 开头。它会被识别为 CUR,并以 .cur 扩展名保存。