ICO 文件格式

存放在github.com上的源代码链接
Go语言处理Windows系统的图标ICO文件(中)
Go语言处理Windows系统的图标ICO文件(下)


概述

我们在编写一个程序后,如果是windows系统中的程序,我们希望它有一个图标,这个时候,我们可以使用一些软件来完成图标,嗯…但是好的Icon制作软件要收费,例如Axialis IconWorkshop,可以制作Windows以及MacOS等系统的图标。网络上基于Web页面的在线转转换工具也是有的,但是我看了下,貌似只是单Image(jpg or png or bmp)转单icon格式,而一个Windows应用程序实际上用到的ico文件,应该是多icon图标的,即一个ico文件内,包含了多个icon图标图像数据。例如下图:

我们可以通过PE Explorer 看到一个Windows的应用程序中,包含图标有多个不同分辨率及不同颜色数量的icon,从Windows Vista开始,windows可以支持的图标分辨率可以达到256x256@32bit的图标资源,既然我们的口号是I am a Gopher!,那么我们无论是从学习角度,还是从Go Code角度,我们完全可以自己实现一个我们自己的Icon工具。


单个icon文件分析

单个icon文件的意思是:我们要分析的ico文件只包含了一个图标,实际上ico文件是一种目录结构的文件,即文件内的数据格式结构是可以存放多文件(多个ico图标),为了将理解流程简化,所以我们先观察只在文件结构中存放了一张图标的ico文件。

我这里首先来分析一个16x16pixel@24bit 的ico文件:

资源管理器中显示的2KB大小是一个大概的值,我们鼠标右键菜单,点击属性查看实际大小:

我们看到是1.12KB,实际大小为1150字节。(1150 / 1024 = 1.123046875 round 1.12KB)

我们再查看文件的HEX(Binary二进制文件,通常我们用16进制查看器来阅读)

我框选的部分有22个字节,这22个字节就是我们这个ico文件的header部分,我们通常称之为文件头(用于描述文件结构的概念)
然后我们通过下面这张图来充分理解,每个字节的含义:

首先根据Windows系统下ico文件格式的标准,存储的数据采用的是little-endian即“小端序”。
什么是小端序,我们可以理解为:数据的低位在前,高位在后,即个十百千-> 1024 -> 4201
在16进制查看器中,例如:

var data uint32 = 255

那么小端序存储在内存或磁盘的方式为:

FF 00 00 00|-  255的16进制
var data uint32 = 256

那么一个字节能够表示的最大正整数为255,这里256,超出了1位:

00 01 00 00|----|- 进位了,256的16进制为100

关于小端序的数据转换,这里先说一下代码:

var data = []byte{0x00, 0x01, 0x00, 0x00}
Int32Data := binary.LittleEndian.Uint32(data[0:])
t.Logf("%v", Int32Data)

输出结果:

=== RUN   Test_LittleEndian
--- PASS: Test_LittleEndian (0.00s)main_test.go:144: 256 // 这里是结果
PASS
ok      ICOFormat 0.187s

现在我们将概念的理解转换为代码:

type winIcon struct {reservedA     uint16 // 保留字段,始终为 '0x0000'fileType      uint16 // 图像类型:'0x0100' 为 ico,'0x0200' 为 curimageCount    uint16 // 图像数量:至少为 '0x0100' 即 1个图标width         uint8  // 图像宽度height        uint8  // 图像高度palette       uint8  // 调色板颜色数,不使用调色版为 '0x00'reservedB     uint8  // 保留字段,始终为 '0x00'colorPlanes   uint16 // 在ico中,指定颜色平面,'0x0000' 或则 '0x0100'bitsPerPixel  uint16 // 在ico中,指定每像素的位数,如:'0x2000' 32bitimageDataSize uint16 // 图像数据的大小,单位字节imageOffset   uint32 // 图像数据的偏移量
}

等一等,这似乎只是单图标文件的结构描述,我们前面说了,ico文件内部应该是以目录结构描述的。
而且图像的数据可以是bmp(Bitmap位图),也可以是png(Portable Network Graphics便携式网络图形)格式。


多个ico图标结构分析

所以我们再来看一个多icon图标文件的ico文件结构:

上图中橘黄色的框中为BMP或PNG的数据偏移量,0x960100 -> 小端转换后为:406字节
那么后面的数据段应该是啥样的呢?我们看看从头偏移406字节的内容:

从第一个字节开始偏移406字节的内容选中后,即便我不用不同颜色的框标明一下,都会觉得感觉每一行的结构都好特么的像。再用不同颜色的框一画,聪明的同学肯定感觉一切尽在掌握。哈哈哈。刚好25个…
换句话说,那个BMP或PNG的偏移量表示的就是偏移过后,就是图像数据。而偏移量前的就是我们的ico文件中的头结构。

那么我们可以这样理解ico文件的头结构:
1-6字节:ico文件头,表明ico文件中包含多少个icon图标
7-22字节:ico文件结构头,主要说明图像数据的偏移量
而19至22字节的偏移量则是我们整个单或多ico图标ico文件的头结构。

那么我们来将理解转换代码:

type WinIcon struct {fileHeader *winIconFileHeader // 文件头icos       []winIconStruct    // icon 头结构data       []byte             // 所有ico文件数据
}type winIconHeader struct {ReservedA  uint16 // 保留字段,始终为 '0x0000'FileType   uint16 // 图像类型:'0x0100' 为 ico,'0x0200' 为 curImageCount uint16 // 图像数量:至少为 '0x0100' 即 1个图标
}type winIconStruct struct {Width         uint8  // 图像宽度Height        uint8  // 图像高度Palette       uint8  // 调色板颜色数,不使用调色版为 '0x00'ReservedB     uint8  // 保留字段,始终为 '0x00'ColorPlanes   uint16 // 在ico中,指定颜色平面,'0x0000' 或则 '0x0100'BitsPerPixel  uint16 // 在ico中,指定每像素的位数,如:'0x2000' 32bitImageDataSize uint16 // 图像数据的大小,单位字节ImageOffset   uint32 // 图像数据的偏移量
}

下一节文章会讲到如何读取ico文件

Go语言处理Windows系统的图标ICO文件(上)相关推荐

  1. Go语言处理Windows系统的图标ICO文件(中)

    ICO文件格式 存放在github.com上的源代码链接 Go语言处理Windows系统的图标ICO文件(上) Go语言处理Windows系统的图标ICO文件(下) 提取ICO文件中的所有图标图像 在 ...

  2. Go语言处理Windows系统的图标ICO文件(下)

    ICO文件格式 存放在github.com上的源代码链接 Go语言处理Windows系统的图标ICO文件(上) Go语言处理Windows系统的图标ICO文件(中) 将PNG或BMP转换为ICO文件 ...

  3. 《Windows系统文件名详解(上)》

    WINDOWS应用 UNIX|LINUX office软件 其他内容 维修实例 其他 photoshop CorelDraw AutoCAD 其他 程序语言类 数据库类 网站建设 互联网应用 网络安全 ...

  4. windows系统下批量修改文件后缀

    在Windows系统下批量修改文件后缀要用到 ren命令.在使用win10系统的朋友们肯定会发现系统会给自己推荐一些开机锁屏壁纸, 今天就用这个命令批量保存这些壁纸. 这些壁纸文件目录在: C:\Us ...

  5. windows 系统开机后-按键盘上的字母会出现数字-如何解决

    windows 系统开机后-按键盘上的字母会出现数字-如何解决   原因:你的注册表有问题了:1.首先打开注册表(也可以在开始-->运行-->输入regedit 直接打开)       2 ...

  6. C# 获取Windows系统ICON图标的四种方式-可提取各种文件夹、文件等等图标

    本文介绍的是提取Windows系统内部Icon图标的方法,就是系统资源管理器里面显示的图标,包括文件夹.文件,如:常规文件夹的图标.特定文件夹图标(磁盘根目录.收藏夹.网络共享目录等).各文件类型图标 ...

  7. Windows系统下隐藏的文件

    Windows下隐藏的文件有哪些? 怎样在没有准备专用软件的情况下,更快.更有效地保护自己的私人资料,而不让他人发现呢?今天,笔者结合自己的经验和他人的使用情况,谈谈如何在Windows下," ...

  8. 怎样搜索计算机文档,怎么样快速搜索电脑文件 Windows系统秒搜电脑文件

    不知大家有没有遇到过这样的情况,当电脑里储存的文件越来越多的时候,就会经常找不到需要用到的文件放在什么地方,遇到急需该文件却又忘了放在什么位置的时候是最气的!而如果我们使用Windows自身的全盘搜索 ...

  9. Windows系统 Prefetch目录 *.pf 文件解析 -- 探索程序运行记录、保护隐私

    一.前言 1.本文说明 如果喜欢打开XX软件看XX视频等,看了多少次,什么时候看的,都会被记录下来,用软件来查看一下,全部的隐私都没有了. 家里的小孩玩的啥游戏,玩了多少次,也都可以看得一清二楚. 查 ...

最新文章

  1. 基于html5海贼王单页视差滚动特效
  2. 使用Jenkins自动远程调用压测机实现不同用户场景下的并发测试
  3. Android之用户定位(二)
  4. 12306 说:有时候,能排队也是一种幸福!
  5. 多线程生成随机数组+多线程快速排序(C++实现)
  6. VTK:可视化算法之ImageGradient
  7. 芒果TV崩了?项目组在家办公效率不行呀!
  8. python中reduce函数_Python中的reduce()函数
  9. iOS开发之#iPhone6与iPhone6Plus适配#Xcode6.0/Xcode6.1上传应用过程中一些变动以及#解决方案#
  10. JAVA常用工具类→Date、SimpleDateFormat、Calendar、System、Math
  11. 生日python十种日期格式_Python可视化-二十四节气与生日间隔天数统计
  12. 文库网站开发,文库网站定制,仿百度在线文档网站建设
  13. 陕西西安职高计算机学校有哪些,2019西安中职学校名单(含公办与民办名单)...
  14. 微信小程序--萌系登陆界面
  15. erlang 之简单的Diction实现
  16. 管理好团队的七个要点,你做到了几个?
  17. https://juejin.im/entry/58622ebc570c3500694ec86c
  18. Dijkstra算法和Floyd算法详解(MATLAB代码)
  19. php表格升序降序,excel如何实现升序和降序
  20. 怎么下载微信朋友圈的ppt存为己用

热门文章

  1. Python创建自己的聊天机器人
  2. vim 下 :normal模式
  3. 微信企业号手机端清理缓存
  4. Antv踩坑—导入画布数据监听画布渲染完成事件
  5. Eltra EL40A1024Z5/28P6X6PR2.004C
  6. JAY和ZOOM,还有铁面人究竟是谁?
  7. Shell脚本之免交互
  8. Zeppelin-0.9.0同步Apache DS LDAP 方案
  9. Zeppelin Job monitor打开
  10. matlab基础总结与图像处理应用(上)