ico文件的数据结构_第1页
ico文件的数据结构_第2页
ico文件的数据结构_第3页
ico文件的数据结构_第4页
ico文件的数据结构_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

./1.制造原理

调色板模式的ico文件的数据结构,可分为6部分:

1.ICON文件头〔6字节〕

2.ICON图象信息块〔16字节〕

3.BMP信息头〔40字节〕

4.调色板〔16色为64字节,256色为1024字节〕

5.XOR位图

6.AND位图而调色板模式的bmp文件的数据结构可分为4部分:

1.BMP文件头〔14字节〕

2.BMP信息头〔40字节〕

3.调色板〔16色为64字节,256色为1024字节〕

4.XOR位图分析可知,ico图标与bmp位图有三个相同的部分〔注:真彩图标与真彩位图的数据结构

均没有调色板部分,所以是两个相同的部分〕,而且这三个部分是最重要的部分。因此,我

们只要去掉bmp位图的BMP文件头,再加上ICON文件头、ICON图象信息块和AND位图,就可

以轻松制作出255×255象素以内的任何规格的图标了。然而……且慢,有一点却是很不轻松

的:如果你想制作背景透明〔屏蔽背景色〕的图标,那么你还需要对XOR位图的数据动大手

术,更不轻松的是,AND位图的数据也必须符合相应的要求,这是相当困难的;而制作有背

景色的图标的话,XOR位图部分我们可以原封不动,AND位图全是0,只要计算出它的长度

来即可添加到XOR位图数据的后面,这是很容易实现的。所以,下面我所讲的,都是制作有

背景色的图标。

ICON文件头结构很简单,一共只有3个数据共6个字节,我们要给其中的"资源类型"和

"图象个数"2个数据均赋值为1。

ICON图象信息块有7个数据共16字节,有5个数据要赋值:图标宽度、图标高度、颜色

计数、图像数据块的长度、图象数据块相对于文件头部的偏移量。要赋值的5个数据中,图

象数据块相对于文件头部的偏移量是固定的,图像数据块的长度需要计算,其余3个数据可

从BMP信息头中获得资料。

AND位图的长度必须根据从BMP信息头中获得的有关数据计算。

此外,还要更改BMP信息头中的2个数据:一个是图象长度数据〔要加上AND位图的

长度〕,另一个是图像高度数据〔这只要简单地将原数据×2即可〕。

OK,一切都准备好了,万事俱备,只欠东风,下面就让东风劲吹吧。2.编程

新建一个窗体,添加一个公用对话框,两个图片框,三个按纽。

窗体与图片框的ScaleMode属性均设为3,其中Picture1的Autosize属性设为Ture。

按纽的属性设置:

Command1:Caption=打开图片

Command2:Caption=数据处理,Enabled=False

Command3:Caption=保存图标,Enabled=False代码如下:OptionExplicitDimpDAT<>AsByte'源图数据

DimaDAT<>AsByte'AND位图数据

DimiDAT<>AsByte'icon文件头和图象信息块数据PrivateSubCommand2_Click<>

OnErrorGoTo100

DimdAsLong,cAsLong

DimaLengthAsLong'AND位图长度aLength=4*<pDAT<4>\32+Abs<<pDAT<4>Mod32>>0>>*pDAT<8>'计算AND位图的长度

ReDimaDAT<aLength-1>AsByte

ReDimiDAT<21>AsByte'给icon文件头和icon图象信息块的元素赋值

iDAT<2>=1'资源类型

iDAT<4>=1'图像个数

iDAT<6>=pDAT<4>'图像宽

iDAT<7>=pDAT<8>'图像高

iDAT<8>=16*Abs<pDAT<14>=4>

iDAT<18>=22'图象数据块相对于文件头部的偏移量'更改BMP信息头中的图像高度数据

d=2*pDAT<8>

SelectCaseLen<Hex<d>>

Case1,2:pDAT<8>=d

Case3,4:pDAT<9>=d\256:pDAT<8>=dAnd255

EndSelect'更改BMP信息头中的图象长度数据

c=pDAT<21>:d=pDAT<20>+c*256+pDAT<22>*65536+aLength

SelectCaseLen<Hex<d>>

Case1,2:pDAT<20>=d

Case3,4:pDAT<21>=d\256:pDAT<20>=dAnd255

Case5,6:c=dAnd65535:pDAT<22>=d\65536:pDAT<21>=c\256:pDAT<20>=cAnd255

EndSelect'计算icon图像信息块中的图象长度数据

SelectCasepDAT<14>'pDAT<14>=4为16色,=8为256色,=24为真彩

Case4:d=d+40+64'64是16色调色板长度,40是BMP信息头的长度

Case8:d=d+40+1024'1024是256色调色板长度

Case24:d=d+40

EndSelect

SelectCaseLen<Hex<d>>

Case1,2:iDAT<14>=d

Case3,4:iDAT<15>=d\256:iDAT<14>=dAnd255

Case5,6:c=dAnd65535:iDAT<16>=d\65536:iDAT<15>=c\256:iDAT<14>=cAnd255

EndSelectCommand3.Enabled=True:Command2.Enabled=False

100

EndSubPrivateSubCommand1_Click<>

OnErrorGoToReadErr

DimImageNameAsString,fLengthAsLong,BJAsBoolean

WithCommonDialog1

.DialogTitle="打开"

.Filter="图片文件<*.bmp,*.jpg,*.gif>|*.bmp;*.jpg;*.gif"

.ShowOpen

IfLen<.FileName><5ThenExitSub

ImageName=.FileName

EndWith

Picture1.Picture=LoadPicture<ImageName>

Picture2.Width=Picture1.Width:Picture2.Height=Picture1.Height

Picture2.Picture=LoadPicture<>

IfRight<LCase<ImageName>,3><>"bmp"Then'如果不是位图,先存为位图,再读取

BJ=True

ImageName=App.Path&"\TempFile.bmp"

SavePicturePicture1.Image,ImageName

EndIf

fLength=FileLen<ImageName>'获取文件长度

ReDimpDAT<fLength-15>AsByte

OpenImageNameForBinaryAs#1

Get#1,15,pDAT

Close

IfBJThenKillImageName'删除临时位图文件

If<pDAT<5>+pDAT<6>+pDAT<7>+pDAT<9>+pDAT<10>+pDAT<11>>0>Then

MsgBox"图片尺寸超出"

ExitSub

EndIf

Me.Caption=ImageName

Command2.Enabled=True

ExitSub

ReadErr:

Close

EndSubPrivateSubCommand3_Click<>

OnErrorGoToWriteErr

DimIconNameAsString

WithCommonDialog1

.Flags=&H802

.DialogTitle="保存"

.Filter="图标文件<*.ico>|*.ico"

.ShowSave

If.FileName=""ThenExitSub

IconName=.FileName

EndWith

OpenIconNameForBinaryAs#1

Put#1,,iDAT

Put#1,,pDAT

Put#1,,aDAT

Close

ReDimiDAT<0>

ReDimpDAT<0>

ReDimaDAT<0>

Command3.Enabled=False

Picture2.Picture=LoadPicture<IconName>

ExitSub

WriteErr:

Close

MsgBox"图标制作失败"

EndSub3.代码分析

①在Command1_Click过程中,使用二进制读入数据方法,从第15字节读起,这样就去掉了

BMP文件头。②在Command3_Click过程中,使用二进制写入数据方法,将ICON文件头、ICON图象信息块

、读入的位图数据〔修改了其中几个字节的数据〕、AND位图数据〔全0数据>等,依次写入一

个ico文件③Command2_Click过程是本代码关键的关键。

首先计算AND位图的长度。这就需要知道扫描线的长度和图象的高度,而计算扫描线长度

还需知道图像的宽度。本代码中,图像高度在原位图数据的pDAT<8>元素中,图象宽度在原位

图数据的pDAT<4>元素中,所以可归纳成代码中所示的计算公式。接着给ICON文件头和ICON图象信息块的元素赋值。请注意iDAT<6>和iDAT<7>,它们

分别是图标的宽度和高度,由于它们都只占用1个字节,故图标规格的最大值只能做到255

象素〔如果它们都分别占用4个字节的话,呵呵,那制作出来的图标是多么地惊人啊!〕。

icon图像信息块中的图象长度数据元素iDAT<14>—iDAT<17>要最后才赋值。接下来就是更改BMP信息头中的图像高度数据。原元素中只是XOR位图的高度,而图标的

数据结构要求这个值是XOR位图高度与AND位图高度之和。再修改BMP信息头中的图象长度数据。原元素中只是XOR位图的长度,而图标的数据结

构要求这个值是XOR位图长度与AND位图长度之和。最后修改icon图像信息块中的图象长度数据,也就是iDAT<14>—iDAT<17>元素的值

〔这个长度数据本来占用4个字节,但255×255象素的图标长度只要3个字节就够了〕。计

算公式如下:icon图像信息块中的图象长度=XOR位图长度+AND位图长度+BMP信息头长度+调色板长度

特大图标的制作工作到此就全部结束了,你一定迫不与待地想看看它的效果吧,可惜的

是,不论多大的图标,在桌面或资源管理器中最大都只能显示72×72的尺寸,你只有在图片

框中才能欣赏到它的丽容了。不过不要垂头丧气,通过这个实验,你将会获得许多图标与位

图的数据结构方面的知识,这不就是最大的收获吗?

附:图标文件的数据结构之研究一、从图标的显示原理说起

一般图标都是由两个单独的位图组成的。如果该图标是屏蔽背景色的话,那么,第一个

位图是由黑色背景〔相关的颜色位全为0〕与彩色图标图案组成的,该位图将与当前屏幕进

行异或操作〔XOR〕,故称其为XOR位图;第二个位图是由白色背景〔相关的颜色位全为1〕

与黑色图标图案〔相关的颜色位全为0〕组成的,该位图将与当前屏幕进行与操作〔AND〕,

故称其为AND位图。因此,图标的显示是通过两个步骤完成的:步骤1.首先,AND位图与当前屏幕进行AND操作;

步骤2.接着,XOR位图与当前屏幕进行XOR操作。大家知道,任何数值与1进行AND操作的结果将等于原数值,而任何数值与0进行AND

操作的结果则是0,因此在步骤1中,AND位图中的背景色〔即白色1〕部分与屏幕经过AND

操作后仍然保持屏幕的原色彩,而图案色〔即黑色0〕部分则取代了原屏幕色。步骤1结束

后,屏幕上将留下一个黑色的图标图案。在随后的步骤2中,由于任何数值与0进行异或操

作的结果都等于原数值,因此,XOR位图与屏幕经过异或操作后,彩色图案部分就取代了屏

幕上的黑色图标部分,而屏幕的背景色与XOR位图中的黑色背景0异或后仍保持原来的屏幕

色。步骤2结束后,一个以屏幕色为背景的彩色图标图案就出现在屏幕上了〔这也是我们通

常所说的"屏蔽背景色"或者说"背景色透明"〕,这就是图标显示的原理。二、图标的图形

图标的图形,实际上就是位图格式的图片,是一个标准的位图格式。Windows只要从BMP

信息头中获取信息就足够了,它据以解释在其后出现的数据应该如何处理。如果是调色板模

式,BMP信息头后面的数据包含有调色板和像素点颜色索引,如果是真彩模式,其后的数据

直接就是像素点的RGB颜色值。

调色板模式的位图文件是由BMP文件头、BMP信息头、调色板、数据区〔又称位图点阵〕

等几个部分组成的。

而调色板模式的图标文件是由ICON文件头、ICON图像信息块、BMP信息头、调色板、数

据区〔这个数据区比位图的数据区多了AND位图的数据,后面会讲到〕。

我们欣喜地看到,位图与图标的数据结构有很大一部分是相同的!了解了这一情况,我

们可以简单地把图标图形的结构理解为位图信息。这样,我们就有可能根本不需要真的去画

一幅图来制作图标,而只需要利用已有的位图,对关键数据进行程序填充或修改就可以了,

所编写的代码,直接按图标格式的要求,可把一个尺寸不大于255×255像素的任意位图,

封装成标准格式的图标〔位图的宽高尺寸保持不变〕。

三、图标的数据结构

图标文件的数据结构可分为6部分,叙述如下:

顺号名称长度〔单位:字节〕说明

1ICON文件头6

2ICON图象信息块16有多少个图像,则信息块也有多少个

3BMP信息头40

4XOR位图调色板16色=64,256色=1024真彩图标从此开始像素点的RGB值

5XOR位图以调色板的索引值形式表示

6AND位图以单色表示

说明:

1.上表中的3-6部分合称图像数据块,其中5、6部分又合称为图像数据区〔也称位图点阵〕

2.不论何种规格的图标,其1-3部分的字节长度是固定的。

3.调色板是供XOR位图使用的,所以又称作XOR位图调色板。AND位图是不需要调色板的,因

为它是单色的,即只有黑色和白色,所以又称作单色AND位图。

4.请注意第2部分的图象信息块的说明,"有多少个图像"是什么意思呢?原来,在一个图

标文件中,有可能存放几个图像〔windows图标最多可有8个图像〕,但每个图像都有自己

的BMP信息头、调色板、XOR位图和AND位图,且它们的图像大小也可能不相同。以16

色有3个图像的图标为例,其数据结构如下:

顺号名称长度〔字节〕说明

1文件头

6

2图象1的图象信息块

16

3图象2的图象信息块

16

4图象3的图象信息块

16

5图象1的图象数据块

不定其中BMP信息头和调色板固定为40和64字节

6图象2的图象数据块

不定同上

7图象3的图象数据块

不定同上

下面以内含1个图像、16色、16×16规格的图标为例详述〔偏移量括号前为10进制,括

号内为16进制〕:

偏移量字节数描述典型值〔16进制〕

〔一、文件头6字节〕

000〔000〕2保留的字节0000

002〔002〕2资源类型0100〔01为图标,02为光标〕

004〔004〕2图象个数0100

〔二、图像信息块16字节〕

006〔006〕1图标宽度10

007〔007〕1图标高度10

008〔008〕1颜色计数10〔16色,02=单色,00=256色或真彩>

009〔009〕1未用00

010〔00A〕4保留的00000000

014〔00E〕4图象数据块的长度

28010000〔10进制=296〕

018〔012〕4图象数据块相对于文件头部的偏移量16000000〔10进制=22〕

〔三、BMP信息头40字节〕

022〔016〕4BMP信息头结构长度28000000〔10进制=40〕

026〔01A〕4图像宽度10000000

030〔01E〕4图像高度〔XOR图高度+AND图高度〕20000000

034〔022〕2位面板数

0100

036〔024〕2每象素所占位数

0400〔04=16色,8=256色,18=真彩>

038〔026〕4象素数据的压缩类型00000000〔表示未压缩〕

042〔02A〕4位图点阵的长度C0000000〔10进制=192〕

046〔02E〕16未用16个00.

〔四、XOR位图的调色板64字节〕

062〔03E〕1蓝色分量

063〔03F〕1绿色分量

064〔040〕1红色分量

065〔041〕1未用00

……

〔五、XOR位图的数据128字节〕

126〔07E〕128XOR位图

〔六、单色AND位图的数据64字节〕

254〔0FE〕64AND位图

说明:

1.上表中有关长度的数据,遵循"低位在前,高位在后"的原则。如果有4个字节,那么后2

个字节为高位,前2个字节为低位,并且每2个字节内也是"低位在前,高位在后"。例如

偏移量为00E的图象数据块的长度是28010000,在计算时要把它们反过来,变成0000

0128,实际就是16进制的128即10进制的296;再如12345678,那么实际计算时就是:

78563412,即10进制的2018915346

2.偏移量为024的"每象素所占位数"是指象素在XOR位图中所占的字节位数〔1个字节=8位〕

,04表示每个象素占4位,换言之,就是说XOR位图中每个字节可表示2个象素。该数据如为

0100,则表示单色〔黑白位图〕,0400为16色,0800为256色,1800为24位真彩。

3.XOR位图每字节对应2个像素<16色>或1个像素<256色>,它的排列规律是:倒向〔最末行的

像素在最前,而第一行的像素在最后,由此类推〕,行内像素按从左至右的顺序,字节高

位表示靠左的像素。AND位图每字节对应8个象素〔每位对应1个象素〕,排列规律与XOR位

图相同。

4.真彩图标没有调色板,而是在第3部分BMP信息头的后面直接存放像素的RGB值,24位

真彩图标每3个字节对应1个像素值,其中每个字节分别对应该像素的R、G、B值。像素的

排列规律与调色板模式的图标相同。

5.上表的第一、二、三部分中,凡字节数为1的数据,其数据类型为Byte,字节数为2的数据,

其数据类型为Integer,字节数为4的数据,其数据类型为Long〔第三部分中有16个未用的

的字节,是4个Long类型的数据,它们在.bmp位图中是有作用的〕。下面是各种图标〔内含1个图像〕的调色板、图像数据的长度与总长度,括号内是起始字

节的偏移量:

单位:字节

图标规格调色板XOR位图AND位图总长度

16色16×16象素<62>64<126>128<254>64

318

16色24×24象素<62>64<126>288<414>96

510

16色32×32象素<62>64<126>512<638>128766

16色48×48象素<62>64<126>1152<1278>3841662

256色16×16象素<62>1024<1086>256<1342>641406

256色24×24象素<62>1024<1086>576<1662>961758

256色32×32象素<62>1024<1086>1024<2110>1282238

256色48×48象素<62>1024<1086>2304<3390>3843774

真彩16×16象素

<62>768<830>64

894

真彩24×24象素

<62>1728<1790>961886

真彩32×32象素

<62>3072<3134>1283262

真彩48×48象素

<62>6912<6974>3847358

说明:

1.XOR位图的长度与图标尺寸与图标的颜色数均有关,AND位图的长度只与图标的尺寸有关,

与图标的颜色数无关。

2.XOR位图每字节对应2个像素〔16色〕或1个像素〔256色〕

3.AND位图每4字节为一组〔这里所说的"一组",其标准名称为"一条扫描线",扫描线的

定义是:位图中的一行数据信息叫做一条扫描线〕,但48×48图标的AND位图每8个字节

为一组。组内每个颜色位对应1个象素。注意:

①16×16图标每组的后2个字节不用,所以实际上是2字节〔16位〕对应一行16个象素

②24×24图标每组的最后1个字节不用,所以实际上是3字节〔24位〕对应一行24个象素

③32×32图标每组4个字节32位对应一行32个象素

④48×48图标每组的后2个字节不用,所以实际上是6字节〔48位〕对应一行48个象素

4.为什么位图数据中会有不用的字节呢,这不是浪费吗?原来,Windows有一个规定,每一

条扫描线必须结束于一个32位的边界,也就是说,一条扫描线的位长度〔按位计算〕必须

能整除32,或字节长度必须能整除4〔XOR、AND位图都是如此〕。举例来说,如果一条扫

描线只有8位,那么就要用空白的24位来补充,如果有48位,那么还必须用空白的16位来

补充。

5.XOR位图每条扫描线长度取决于两个因素:图像的宽度值和颜色数。各种颜色的图标的XOR

位图每条扫描线的长度如下表所示〔单位:字节〕:①16色图标:

XOR图象宽度扫描线长度

16象素8

17--24象素12

25--32象素16

33--40象素20

41--48象素24

49--56象素28

57--64象素32

65--72象素36

71--80象素40

……

可以归纳出计算公式是:

16色XOR位图每条扫描线长度=4×〔图象宽\8+Abs〔〔图象宽Mod8〕>0〕〕②256色图标:

XOR图象宽度扫描线长度

16象素16

17--20象素20

21--24象素24

25--28象素28

29--32象素32

33--36象素36

37--40象素40

41--44象素44

45--48象素48

……

可以归纳出计算公式是:

256色XOR位图每条扫描线长度=4×〔图象宽\4+Abs〔〔图象宽Mod4〕>0〕〕③真彩图标:

XOR图象宽度扫描线长度

16象素48

17象素52

18象素56

19象素60

20象素

60

21象素64

22象素68

23象素72

24象素72

……

可以归纳出计算公式是:

真彩XOR位图每条扫描线长度=4×〔图象宽×3\4+Abs〔〔图象宽×3Mod4〕>0〕〕6.AND位图每条扫描线的长度只与图标图像的宽度值有关。如下表所示〔单位:字节〕:

AND图象宽度扫描线长度

16--32象素4

33--64象素8

65--96象素12

97--128象素16

129--160象素20

160--192象素24

192--224象素28

224--255象素32

可以归纳出计算公式是:

AND位图每条扫描线长度=4×〔图象宽\32+Abs〔〔图象宽Mod32〕>0〕〕7.要使背景透明,XOR位图的背景必须为黑色〔对应的颜色位=0〕,图案为彩色,而AND位

图则背景必须为白色〔对应的颜色位=1〕,图案为黑色〔对应的颜色位=0〕

8.XOR位图的彩色图形信息中存储的并不是颜色值,而是与调色板对应的索引值,从0开始

编号。

四、图标的颜色

调色板模式的图标,其颜色是由调色板确定的,而调色板是可以自行定义的。比如16色

图标,其调色板只要有16种颜色就行。下面是以QBasic的16种颜色作为调色板时,XOR位

图调色板的16色索引值与QBColor的颜色值对照:

颜色索引值QBasic调色板中的值〔最后一个字节未用〕

黑色0

0

000000

00

深红1

4

000080

00

深绿2

2

008000

00

深黄3

6

008080

00

深蓝4

1

800000

00

深紫5

5

800080

00

深青6

3

808000

00

深灰7

8

808080

00

浅灰

8

7

C0C0C0

00

红色9

C<12>0000FF

00

绿色A<10>

A<10>00FF00

00

黄色B<11>

E<14>00FFFF

00

蓝色C<12>

9

FF0000

00

紫色D<13>

D<13>FF00FF

00

青色E<14>

B<11>FFFF00

00

白色F<15>

F<15>FFFFFF

00

怎么个对应法呢?举个例来说,比如16×16象素图标的XOR位图中某个字节值为81,那

就表示该字节所对应的2个象素,左边的象素为浅灰色而右边的象素为深红色。五、一个具体的例子

有一个16色16×16象素的图标,该图标是一个边长为16、边框为红色的空心正方形,其

全部数据如下:

偏移量000102030405060708090A0B0C0D0E0F

000

00000100010010101000000000002801

010

00001600000028000000100000002000

020

00000100040000000000C00000000000

030

00000000000000000000000000000000

040

00000000800000800000008080008000

050

0000800080008080000080808000C0C0

060

C0000000FF0000FF000000FFFF

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论