一、ICO 文件整体结构
一个完整的 ICO 文件由三部分依次组成:
- 文件头(File Header):描述文件类型和图标数量
- 图标目录项(Icon Directory Entries):每个目录项对应一个图标图像,记录其尺寸、颜色深度等信息
- 图像数据(Image Data):实际的图像像素数据(位图或 PNG 数据)
二、详细结构解析
1. 文件头(16 字节)
文件头固定为 16 字节,结构如下:
| 偏移(字节) | 字段名 | 长度(字节) | 说明 |
|---|---|---|---|
| 0-1 | Reserved | 2 | 保留字段,必须为 0 |
| 2-3 | Type | 2 | 资源类型:1 表示 ICO 文件,2 表示 CUR(光标)文件 |
| 4-5 | Count | 2 | 图标数量:表示该文件包含多少个不同尺寸 / 颜色深度的图标 |
示例:一个包含 2 个图标的 ICO 文件头可能为:00 00 01 00 02 00 ...(前 6 字节)
00 00:Reserved 为 001 00:Type 为 1(ICO)02 00:Count 为 2(包含 2 个图标)
2. 图标目录项(每个 16 字节,共 Count×16 字节)
每个图标对应一个 16 字节的目录项,记录该图标的元信息:
| 偏移(字节) | 字段名 | 长度(字节) | 说明 |
|---|---|---|---|
| 0 | Width | 1 | 图标宽度(像素):0 表示 256 像素 |
| 1 | Height | 1 | 图标高度(像素):0 表示 256 像素(注意:实际存储为高度 ×2,含掩码) |
| 2 | ColorCount | 1 | 颜色数:0 表示超过 256 色(如 24/32 位) |
| 3 | Reserved | 1 | 保留字段,必须为 0 |
| 4-5 | Planes | 2 | 色彩平面数:通常为 1(仅用于旧格式) |
| 6-7 | BitCount | 2 | 颜色深度(位 / 像素):如 32(32 位真彩色 + Alpha 通道) |
| 8-11 | BytesInRes | 4 | 图像数据大小(字节) |
| 12-15 | ImageOffset | 4 | 图像数据在文件中的偏移量(从文件开头到该图像数据的字节数) |
示例:一个 32×32 像素、32 位颜色的图标目录项可能为:20 20 00 00 01 00 20 00 ...
20(32):Width = 32 像素20(32):Height = 32 像素00:ColorCount = 0(超过 256 色)20 00(32):BitCount = 32 位
3. 图像数据(可变长度)
每个图标的图像数据格式取决于其颜色深度,常见两种类型:
(1)位图格式(传统 ICO)
- 结构:由「像素数据」和「掩码数据」组成(总高度为目录项
Height的 2 倍)- 像素数据:存储图像的颜色信息,按行倒序排列(从图像底部到顶部)
- 掩码数据:黑白位图,用于指定透明区域(1 表示不透明,0 表示透明)
- 32 位颜色深度:每个像素占 4 字节(R、G、B、Alpha),Alpha 通道直接控制透明度,掩码可省略
- 24 位及以下:依赖掩码实现透明,像素数据按 BGR 顺序存储(无 Alpha 通道)
(2)PNG 格式(现代 ICO)
- 从 Windows Vista 开始支持,图像数据直接嵌入完整的 PNG 文件(包含 PNG 头、IHDR 块等)
- 优势:支持压缩,透明度处理更高效,适合高分辨率图标(如 256×256 像素)
三、示例:简单 ICO 文件结构
假设一个包含 1 个 16×16 像素、32 位颜色的 ICO 文件:
plaintext
[文件头(16字节)]
00 00 01 00 01 00 ... (Reserved=0, Type=1, Count=1)
[目录项(16字节)]
10 10 00 00 01 00 20 00 ... (Width=16, Height=16, BitCount=32)
[图像数据(N字节)]
(32位像素数据,共 16×16×4=1024 字节)
...(BGR+Alpha 像素值,按行倒序排列)...
四、与 CUR(光标)文件的区别
CUR 格式结构几乎与 ICO 相同,唯一区别是:
- 目录项中
Reserved字段(偏移 3)被替换为「热点坐标」:- 偏移 3 字节:光标热点 X 坐标
- 偏移 4-5 字节:光标热点 Y 坐标(原
Planes字段位置)
通过解析以上结构,可实现 ICO 文件的读取、修改或创建。例如,程序可根据目录项的 ImageOffset 定位到具体图标数据,再根据 BitCount 解析像素信息。

7888

被折叠的 条评论
为什么被折叠?



