生成ICO图标时多尺寸打包的存储结构

ICO 文件头与目录项如何描述多尺寸

ICO 不是“把一张图片改个后缀”,而是一个可以装入多张图像的容器。它用文件头说明目录数量,用目录项记录每个尺寸的位置,再把 PNG 或 DIB 位图数据放在文件后部;浏览器和操作系统据此选择更合适的图像。

ICO 文件开头固定是 6 字节文件头,字段按小端序存储:

  • 保留字段:2 字节,必须为 0,用于标识这是标准 ICO 结构。
  • 类型字段:2 字节,ICO 通常为 1;光标文件 CUR 使用 2。
  • 图像数量:2 字节,表示后面有多少个目录项。

文件头之后紧接着是图像目录。每个目录项固定为 16 字节,它不是图像本身,而是一条索引记录:

  • 宽度:1 字节。
  • 高度:1 字节。
  • 调色板颜色数:1 字节;真彩色图像通常填 0。
  • 保留字段:1 字节,通常为 0。
  • 颜色平面:2 字节。
  • 每像素位数:2 字节。
  • 图像数据大小:4 字节无符号整数。
  • 图像数据偏移量:4 字节无符号整数。

宽度和高度各只有 1 字节,因此无法直接写出 256。格式约定这两个字段的值为 0 时代表 256 像素,不是 0 像素,也不是缺失尺寸。图像数据大小和偏移量则各占 4 字节,读取器利用它们从文件中截取对应的数据区。

不同尺寸位图在文件中的排列方式

一个 ICO 可以同时包含 16×16、32×32、48×48、64×64 和 256×256 像素的图像。目录项只记录这些图像的尺寸、长度和起始位置,真正的图像内容位于所有目录项之后。

  • 16×16:常见于浏览器标签页或小型列表。
  • 32×32:适合部分工具栏、文件列表和普通快捷方式。
  • 48×48:常见于桌面图标的中等显示场景。
  • 64×64:用于更大的界面图标或高 DPI 场景。
  • 256×256:用于桌面缩略图、启动器或需要放大的显示场景。

ICO 内部主要有两类图像数据。第一类是 PNG,也就是经过压缩、可直接按 PNG 规则解码的数据;第二类是传统 DIB,即设备无关位图,通常包含 BITMAPINFOHEADER、像素数据以及与透明度相关的掩码。

两类数据在目录项中的记录方式相同,都依靠“数据大小”和“数据偏移量”定位。区别在于解析方式:PNG 数据通常以 PNG 文件签名开头,DIB 数据则按位图信息头解释。DIB 在 ICO 中还涉及 XOR 位图与 AND 掩码的组合:XOR 区域保存颜色,AND 掩码用于透明或遮罩效果;其高度字段可能反映两部分叠加后的布局,因此不能机械地把所有字段当作普通 PNG 尺寸。

生成器可能按目录顺序写入图像,也可能为了对齐、压缩或缓存采用其他布局。合格的读取器应始终依据每个目录项的偏移量和长度定位,不能假定“第一张数据紧接目录、后面每张固定排列”。

浏览器选择图标尺寸的判断路径

浏览器处理 favicon 时,通常先看 HTML 中的 <link rel="icon"> 声明,再结合 type、sizes 和资源内容筛选候选项。如果资源是 ICO,浏览器还需要读取 ICO 内部目录,判断其中有哪些尺寸和格式。

实际选择并没有一条适用于所有环境的固定算法。浏览器、操作系统和图标加载组件可能综合考虑目标显示尺寸、设备像素比、色深以及 PNG 或 DIB 兼容性;具体结果取决于浏览器版本、操作系统和设备像素比。

  • 标签页通常需要约 16×16 CSS 像素的图标。
  • 书签或收藏夹可能使用 16×16、32×32 或操作系统指定的其他尺寸。
  • 桌面快捷方式可能请求 48×48、64×64 或 256×256。
  • 高 DPI 屏幕可能为相同的 CSS 尺寸选择更高分辨率资源。

因此浏览器不一定选择最大图像。目标是 16×16 时,直接使用合适的小图通常比把 256×256 解码后缩小更省资源;反过来,放大 16×16 会产生模糊。PNG 与 DIB 的支持和优先级也可能随具体版本变化,不能只根据一个浏览器的结果推断所有平台。

用生成工具检查多尺寸打包结果

使用“生成ICO图标”时,它负责把多个尺寸图像打包到一个 ICO 容器中。具体输出格式、是否写入 PNG、是否保留 DIB,以及压缩方式取决于工具版本,生成后仍应检查文件,而不是只看预览图。

  1. 准备多个正方形源图,建议至少提供 16×16、32×32、48×48、64×64 和 256×256;是否加入 128×128,取决于目标平台和工具支持。
  2. 在工具中选择尺寸集合并生成单个 ICO 文件。源图最好分别导出,而不是先把一张小图强行放大到所有尺寸。
  3. 用图标查看器或十六进制编辑器检查开头 6 字节、图像数量,以及每个 16 字节目录项的大小和偏移量。
  4. 确认每个数据区都在文件范围内,彼此没有意外重叠;若目录项声明的长度超出文件末尾,文件就已损坏。
  5. 分别测试浏览器标签页、书签、桌面快捷方式和高 DPI 屏幕。单一场景显示正常,不代表所有目录项都能被正确选择。

最容易误解的一点:ICO 不是一张图自动缩放

  • 误解:ICO 只是一张 256×256 图片,浏览器会自动把它缩放到所有尺寸。
  • 实际情况:ICO 可以包含多个独立图像目录项,每项指向一段单独的 PNG 或 DIB 数据。
  • 误解:目录项中的宽度或高度为 0,表示尺寸缺失或图像无效。
  • 实际情况:在 ICO 目录中,宽度和高度字段为 0 代表 256 像素。

浏览器或操作系统会根据使用场景选择某个目录项,而不是必然把一张 256×256 图片缩放到所有位置。多尺寸打包的价值,正是让小尺寸保留清晰边缘,让大尺寸保留足够细节,同时把选择权交给读取器。

这篇讲到的工具
关键词: ICO文件结构多尺寸图标图标目录项浏览器图标选择
更多推荐

先固定检测目标:步长决定“漏不漏位置” 人脸打码的第一步不是模糊,而是得到足够完整的人脸框。传统滑动窗口会在图像上逐点取出固定大小的区域,再交给分类器判断;后续的置信度筛选和非极大值抑制(NMS)则负责减少误检与重复框。 窗口位置由左上角

了解更多 >

先区分方向标签与像素数据 图片显示方向由两部分决定:文件里的像素排列,以及 EXIF 中的 Orientation 标签。Orientation 记录的是“显示时如何变换”,不一定代表 JPEG 内部像素已经转正;读取标签、执行变换并同步

了解更多 >

从 RGB 数值映射到灰度亮度 把彩色图片转成黑白,核心不是把红、绿、蓝三个数直接相加后平均,而是按照人眼对不同颜色的敏感程度分配权重。常用的 BT.601/Rec.601 亮度近似公式是: Y = 0.299R + 0.587G +

了解更多 >

统一测试条件,避免质量值失真 这次测试要回答两个问题:WebP 有损模式的质量参数从 100 降到 60 时,文件体积怎样变化,画质又在什么位置开始明显下降。质量值不是“画质保留百分比”,所以不能直接推断质量值降了 40,文件就会缩小 40

了解更多 >

PNG、JPEG与WebP转换:体积、画质与兼容性的测试方法 照片通常应比较JPEG与WebP有损编码;截图、文字和透明图标通常应比较PNG与WebP无损编码。但不能仅凭格式判断体积,必须固定编码器和参数后,实测文件大小、画质与兼容性。

了解更多 >