ico文件的数据结构Word格式.docx
《ico文件的数据结构Word格式.docx》由会员分享,可在线阅读,更多相关《ico文件的数据结构Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
的:
如果你想制作背景透明(屏蔽背景色)的图标,那么你还需要对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
代码如下:
OptionExplicit
DimpDAT()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))
pDAT(20)=d
pDAT(21)=d\256:
pDAT(20)=dAnd255
Case5,6:
c=dAnd65535:
pDAT(22)=d\65536:
pDAT(21)=c\256:
pDAT(20)=cAnd255
计算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
iDAT(14)=d
iDAT(15)=d\256:
iDAT(14)=dAnd255
iDAT(16)=d\65536:
iDAT(15)=c\256:
iDAT(14)=cAnd255
Command3.Enabled=True:
Command2.Enabled=False
100
EndSub
PrivateSubCommand1_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
Me.Caption=ImageName
Command2.Enabled=True
ReadErr:
PrivateSubCommand3_Click()
OnErrorGoToWriteErr
DimIconNameAsString
.Flags=&
H802
保存"
图标文件(*.ico)|*.ico"
.ShowSave
If.FileName="
"
ThenExitSub
IconName=.FileName
OpenIconNameForBinaryAs#1
Put#1,,iDAT
Put#1,,pDAT
Put#1,,aDAT
ReDimiDAT(0)
ReDimpDAT(0)
ReDimaDAT(0)
Command3.Enabled=False
Picture2.Picture=LoadPicture(IconName)
WriteErr:
图标制作失败"
3.代码分析
①在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信息头长度+调色板长度
特大图标的制作工作到此就全部结束了,你一定迫不及待地想看看它的效果吧,可惜的
是,不论多大的图标,在桌面或资源管理器中最大都只能