bmp位图,利用bmp位图制作ICO

0001 利用bmp位图制作ICO 收藏 0002 0003 0004 0005 ' 1.制造原理 0006 ' 调色板模式的ico文件的数据结构,可分为 6 部分: 0007 ' 1.ICON文件头(6字节) 0008 ' 2.ICON图象信息块(16字节) 0009 ' 3.BMP信息头(40字节) 0010 ' 4.调色板(16色为64字节,256色为1024字节) 0011 ' 5.XOR位图 0012 ' 6.AND位图 0013 0014 ' 而调色板模式的bmp文件的数据结构可分为 4 部分: 0015 ' 1.BMP文件头(14字节) 0016 ' 2.BMP信息头(40字节) 0017 ' 3.调色板(16色为64字节,256色为1024字节) 0018 ' 4.XOR位图 0019 0020 ' 分析可知,ico图标与bmp位图有三个相同的部分(注:真彩图标与真彩位图的数据结构 0021 ' 均没有调色板部分,所以是两个相同的部分),而且这三个部分是最重要的部分。因此,我 0022 ' 们只要去掉 bmp位图的 BMP文件头,再加上ICON文件头、ICON图象信息块和AND位图,就可 0023 ' 以轻松制作出255×255象素以内的任何规格的图标了。然而……且慢,有一点却是很不轻松 0024 ' 的:如果你想制作背景透明(屏蔽背景色)的图标,那么你还需要对 XOR位图的数据动大手 0025 ' 术,更不轻松的是,AND 位图的数据也必须符合相应的要求,这是相当困难的;而制作有背 0026 ' 景色的图标的话,XOR 位图部分我们可以原封不动,AND 位图全是 0,只要计算出它的长度 0027 ' 来即可添加到 XOR位图数据的后面,这是很容易实现的。所以,下面我所讲的,都是制作有 0028 ' 背景色的图标。 0029 ' ICON文件头结构很简单,一共只有3个数据共6个字节,我们要给其中的“资源类型”和 0030 ' “图象个数” 2个数据均赋值为 1。 0031 ' ICON 图象信息块有 7个数据共16字节,有5个数据要赋值:图标宽度、图标高度、颜色 0032 ' 计数、图像数据块的长度、图象数据块相对于文件头部的偏移量。要赋值的 5个数据中,图 0033 ' 象数据块相对于文件头部的偏移量是固定的,图像数据块的长度需要计算,其余 3个数据可 0034 ' 从 BMP 信息头中获得资料。 0035 ' AND 位图的长度必须根据从 BMP 信息头中获得的有关数据计算。 0036 ' 此外,还要更改 BMP 信息头中的 2个数据:一个是图象长度数据(要加上 AND 位图的 0037 ' 长度),另一个是图像高度数据(这只要简单地将原数据×2即可)。 0038 ' OK,一切都准备好了,万事俱备,只欠东风,下面就让东风劲吹吧。 0039 0040 ' 2.编程 0041 ' 新建一个窗体,添加一个公用对话框,两个图片框,三个按纽。 0042 ' 窗体与图片框的ScaleMode属性均设为3,其中 Picture1 的 Autosize 属性设为 Ture。 0043 ' 按纽的属性设置: 0044 ' Command1:Caption=打开图片 0045 ' Command2:Caption=数据处理,Enabled=False 0046 ' Command3:Caption=保存图标,Enabled=False 0047 0048 代码如下: 0049 0050 Option Explicit 0051 0052 Dim pDAT() As Byte '源图数据 0053 Dim aDAT() As Byte 'AND位图数据 0054 Dim iDAT() As Byte 'icon文件头和图象信息块数据 0055 0056 Private Sub Command2_Click() 0057 On Error GoTo 100 0058 Dim d As Long, c As Long 0059 Dim aLength As Long 'AND位图长度 0060 0061 aLength = 4 * (pDAT(4) \ 32 + Abs((pDAT(4) Mod 32) > 0)) * pDAT(8) '计算AND位图的长度 0062 ReDim aDAT(aLength - 1) As Byte 0063 ReDim iDAT(21) As Byte 0064 0065 '给 icon文件头和 icon图象信息块的元素赋值 0066 iDAT(2) = 1 '资源类型 0067 iDAT(4) = 1 '图像个数 0068 iDAT(6) = pDAT(4) '图像宽 0069 iDAT(7) = pDAT(8) '图像高 0070 iDAT(8) = 16 * Abs(pDAT(14) = 4) 0071 iDAT(18) = 22 '图象数据块相对于文件头部的偏移量 0072 0073 '更改BMP信息头中的图像高度数据 0074 d = 2 * pDAT(8) 0075 Select Case Len(Hex(d)) 0076 Case 1, 2: pDAT(8) = d 0077 Case 3, 4: pDAT(9) = d \ 256: pDAT(8) = d And 255 0078 End Select 0079 0080 '更改BMP信息头中的图象长度数据 0081 c = pDAT(21): d = pDAT(20) + c * 256 + pDAT(22) * 65536 + aLength 0082 Select Case Len(Hex(d)) 0083 Case 1, 2: pDAT(20) = d 0084 Case 3, 4: pDAT(21) = d \ 256: pDAT(20) = d And 255 0085 Case 5, 6: c = d And 65535: pDAT(22) = d \ 65536: pDAT(21) = c \ 256: pDAT(20) = c And 255 0086 End Select 0087 0088 '计算icon图像信息块中的图象长度数据 0089 Select Case pDAT(14) 'pDAT(14)=4为16色,=8为256色,=24为真彩 0090 Case 4: d = d + 40 + 64 '64是16色调色板长度,40是BMP信息头的长度 0091 Case 8: d = d + 40 + 1024 '1024是256色调色板长度 0092 Case 24: d = d + 40 0093 End Select 0094 Select Case Len(Hex(d)) 0095 Case 1, 2: iDAT(14) = d 0096 Case 3, 4: iDAT(15) = d \ 256: iDAT(14) = d And 255 0097 Case 5, 6: c = d And 65535: iDAT(16) = d \ 65536: iDAT(15) = c \ 256: iDAT(14) = c And 255 0098 End Select 0099 0100 Command3.Enabled = True: Command2.Enabled = False 0101 End Sub 0102 0103 Private Sub Command1_Click() 0104 On Error GoTo ReadErr 0105 Dim ImageName As String, fLength As Long, BJ As Boolean 0106 With CommonDialog1 0107 .DialogTitle = "打开" 0108 .Filter = "图片文件(*.bmp,*.jpg,*.gif)|*.bmp;*.jpg;*.gif" 0109 .ShowOpen 0110 If Len(.FileName) < 5 Then Exit Sub 0111 ImageName = .FileName 0112 End With 0113 Picture1.Picture = LoadPicture(ImageName) 0114 Picture2.Width = Picture1.Width: Picture2.Height = Picture1.Height 0115 Picture2.Picture = LoadPicture() 0116 If Right(LCase(ImageName), 3) <> "bmp" Then '如果不是位图,先存为位图,再读取 0117 BJ = True 0118 ImageName = App.Path & "\TempFile.bmp" 0119 SavePicture Picture1.Image, ImageName 0120 End If 0121 fLength = FileLen(ImageName) '获取文件长度 0122 ReDim pDAT(fLength - 15) As Byte 0123 Open ImageName For Binary As #1 0124 Get #1, 15, pDAT 0125 Close 0126 If BJ Then Kill ImageName '删除临时位图文件 0127 If (pDAT(5) + pDAT(6) + pDAT(7) + pDAT(9) + pDAT(10) + pDAT(11) > 0) Then 0128 MsgBox "图片尺寸超出" 0129 Exit Sub 0130 End If 0131 Me.Caption = ImageName 0132 Command2.Enabled = True 0133 Exit Sub 0134 ReadErr: 0135 Close 0136 End Sub 0137 0138 Private Sub Command3_Click() 0139 On Error GoTo WriteErr 0140 Dim IconName As String 0141 With CommonDialog1 0142 .Flags = &H802 0143 .DialogTitle = "保存" 0144 .Filter = "图标文件(*.ico)|*.ico" 0145 .ShowSave 0146 If .FileName = "" Then Exit Sub 0147 IconName = .FileName 0148 End With 0149 Open IconName For Binary As #1 0150 Put #1, , iDAT 0151 Put #1, , pDAT 0152 Put #1, , aDAT 0153 Close 0154 ReDim iDAT(0) 0155 ReDim pDAT(0) 0156 ReDim aDAT(0) 0157 Command3.Enabled = False 0158 Picture2.Picture = LoadPicture(IconName) 0159 Exit Sub 0160 WriteErr: 0161 Close 0162 MsgBox "图标制作失败" 0163 End Sub 0164 0165 ' 3.代码分析 0166 ' ①在 Command1_Click 过程中,使用二进制读入数据方法,从第15字节读起,这样就去掉了 0167 ' BMP文件头。 0168 0169 ' ②在 Command3_Click 过程中,使用二进制写入数据方法,将ICON文件头、ICON图象信息块 0170 ' 、读入的位图数据(修改了其中几个字节的数据)、AND位图数据(全0数据)等,依次写入一 0171 ' 个ico文件 0172 0173 ' ③Command2_Click 过程是本代码关键的关键。 0174 ' 首先计算 AND位图的长度。这就需要知道扫描线的长度和图象的高度,而计算扫描线长度 0175 ' 还需知道图像的宽度。本代码中,图像高度在原位图数据的 pDAT(8)元素中,图象宽度在原位 0176 ' 图数据的 pDAT(4) 元素中,所以可归纳成代码中所示的计算公式。 0177 0178 ' 接着给 ICON文件头和 ICON图象信息块的元素赋值。请注意 iDAT(6)和 iDAT(7),它们 0179 ' 分别是图标的宽度和高度,由于它们都只占用 1个字节,故图标规格的最大值只能做到 255 0180 ' 象素(如果它们都分别占用 4 个字节的话,呵呵,那制作出来的图标是多么地惊人啊!)。 0181 ' icon 图像信息块中的图象长度数据元素 iDAT(14)—iDAT(17)要最后才赋值。 0182 0183 ' 接下来就是更改BMP信息头中的图像高度数据。原元素中只是XOR位图的高度,而图标的 0184 ' 数据结构要求这个值是XOR位图高度与AND位图高度之和。 0185 0186 ' 再修改 BMP信息头中的图象长度数据。原元素中只是 XOR位图的长度,而图标的数据结 0187 ' 构要求这个值是 XOR位图长度与 AND位图长度之和。 0188 0189 ' 最后修改 icon 图像信息块中的图象长度数据,也就是 iDAT(14)—iDAT(17) 元素的值 0190 ' (这个长度数据本来占用 4个字节,但255×255象素的图标长度只要 3个字节就够了)。计 0191 ' 算公式如下: 0192 0193 ' icon图像信息块中的图象长度=XOR位图长度+AND位图长度+BMP信息头长度+调色板长度 0194 0195 0196 ' 特大图标的制作工作到此就全部结束了,你一定迫不及待地想看看它的效果吧,可惜的 0197 ' 是,不论多大的图标,在桌面或资源管理器中最大都只能显示72×72的尺寸,你只有在图片 0198 ' 框中才能欣赏到它的丽容了。不过不要垂头丧气,通过这个实验,你将会获得许多图标及位 0199 ' 图的数据结构方面的知识,这不就是最大的收获吗? 0200 0201 0202 ' 附:图标文件的数据结构之研究 0203 0204 ' 一、从图标的显示原理说起 0205 ' 一般图标都是由两个单独的位图组成的。如果该图标是屏蔽背景色的话,那么,第一个 0206 ' 位图是由黑色背景(相关的颜色位全为 0)与彩色图标图案组成的,该位图将与当前屏幕进 0207 ' 行异或操作(XOR),故称其为 XOR位图;第二个位图是由白色背景(相关的颜色位全为1) 0208 ' 与黑色图标图案(相关的颜色位全为0)组成的,该位图将与当前屏幕进行与操作(AND), 0209 ' 故称其为 AND 位图。因此,图标的显示是通过两个步骤完成的: 0210 0211 ' 步骤1.首先,AND 位图与当前屏幕进行 AND 操作; 0212 ' 步骤2.接着,XOR 位图与当前屏幕进行 XOR 操作。 0213 0214 ' 大家知道,任何数值与 1 进行AND操作的结果将等于原数值,而任何数值与 0 进行AND 0215 ' 操作的结果则是 0,因此在步骤1中,AND位图中的背景色(即白色 1)部分与屏幕经过 AND 0216 ' 操作后仍然保持屏幕的原色彩,而图案色(即黑色 0)部分则取代了原屏幕色。步骤 1结束 0217 ' 后,屏幕上将留下一个黑色的图标图案。在随后的步骤 2中,由于任何数值与 0 进行异或操 0218 ' 作的结果都等于原数值,因此,XOR 位图与屏幕经过异或操作后,彩色图案部分就取代了屏 0219 ' 幕上的黑色图标部分,而屏幕的背景色与 XOR位图中的黑色背景 0异或后仍保持原来的屏幕 0220 ' 色。步骤 2结束后,一个以屏幕色为背景的彩色图标图案就出现在屏幕上了(这也是我们通 0221 ' 常所说的“屏蔽背景色”或者说“背景色透明”),这就是图标显示的原理。 0222 0223 ' 二、图标的图形 0224 ' 图标的图形,实际上就是位图格式的图片,是一个标准的位图格式。Windows只要从BMP 0225 ' 信息头中获取信息就足够了,它据以解释在其后出现的数据应该如何处理。如果是调色板模 0226 ' 式,BMP 信息头后面的数据包含有调色板和像素点颜色索引,如果是真彩模式,其后的数据 0227 ' 直接就是像素点的 RGB 颜色值。 0228 ' 调色板模式的位图文件是由BMP文件头、BMP信息头、调色板、数据区(又称位图点阵) 0229 ' 等几个部分组成的。 0230 ' 而调色板模式的图标文件是由ICON文件头、ICON图像信息块、BMP信息头、调色板、数 0231 ' 据区(这个数据区比位图的数据区多了 AND 位图的数据,后面会讲到)。 0232 ' 我们欣喜地看到,位图与图标的数据结构有很大一部分是相同的!了解了这一情况,我 0233 ' 们可以简单地把图标图形的结构理解为位图信息。这样,我们就有可能根本不需要真的去画 0234 ' 一幅图来制作图标,而只需要利用已有的位图,对关键数据进行程序填充或修改就可以了, 0235 ' 所编写的代码,直接按图标格式的要求,可把一个尺寸不大于 255×255 像素的任意位图, 0236 ' 封装成标准格式的图标(位图的宽高尺寸保持不变)。 0237 ' 三、图标的数据结构 0238 ' 图标文件的数据结构可分为6部分,叙述如下: 0239 ' ----------------------------------------------------------------------- 0240 ' 顺号 名称 长度(单位:字节) 说明 0241 ' ----------------------------------------------------------------------- 0242 ' 1 ICON文件头 6 0243 ' 2 ICON图象信息块 16 有多少个图像,则信息块也有多少个 0244 ' 3 BMP 信息头 40 0245 ' 4 XOR 位图调色板 16色=64,256色=1024 真彩图标从此开始像素点的 RGB 值 0246 ' 5 XOR 位图 以调色板的索引值形式表示 0247 ' 6 AND 位图 以单色表示 0248 ' ----------------------------------------------------------------------- 0249 ' 说明: 0250 ' 1.上表中的3-6部分合称图像数据块,其中5、6部分又合称为图像数据区(也称位图点阵) 0251 ' 2.不论何种规格的图标,其1-3部分的字节长度是固定的。 0252 ' 3.调色板是供XOR位图使用的,所以又称作XOR位图调色板。AND位图是不需要调色板的,因 0253 ' 为它是单色的,即只有黑色和白色,所以又称作单色AND位图。 0254 ' 4.请注意第 2部分的图象信息块的说明,“有多少个图像”是什么意思呢?原来,在一个图 0255 ' 标文件中,有可能存放几个图像(windows图标最多可有8个图像),但每个图像都有自己 0256 ' 的 BMP 信息头、调色板、XOR 位图和 AND 位图,且它们的图像大小也可能不相同。以16 0257 ' 色有 3 个图像的图标为例,其数据结构如下: 0258 ' ------------------------------------------------------------------------- 0259 ' 顺号 名称 长度(字节) 说明 0260 ' ------------------------------------------------------------------------- 0261 ' 1 文件头 6 0262 ' 2 图象1的图象信息块 16 0263 ' 3 图象2的图象信息块 16 0264 ' 4 图象3的图象信息块 16 0265 ' 5 图象1的图象数据块 不定 其中BMP信息头和调色板固定为40和64字节 0266 ' 6 图象2的图象数据块 不定 同上 0267 ' 7 图象3的图象数据块 不定 同上 0268 ' ------------------------------------------------------------------------- 0269 0270 ' 下面以内含1个图像、16色、16×16规格的图标为例详述(偏移量括号前为10进制,括 0271 ' 号内为16进制): 0272 ' ------------------------------------------------------------------------------------ 0273 ' 偏移量 字节数 描述 典型值(16进制) 0274 ' ------------------------------------------------------------------------------------ 0275 ' (一、文件头6字节) 0276 ' 000(000)2 保留的字节 00 00 0277 ' 002(002)2 资源类型 01 00 (01为图标,02为光标) 0278 ' 004(004)2 图象个数 01 00 0279 ' (二、图像信息块16字节) 0280 ' 006(006)1 图标宽度 10 0281 ' 007(007)1 图标高度 10 0282 ' 008(008)1 颜色计数 10(16色,02=单色,00=256色或真彩) 0283 ' 009(009)1 未用 00 0284 ' 010(00A)4 保留的 00 00 00 00 0285 ' 014(00E)4 图象数据块的长度 28 01 00 00(10进制=296) 0286 ' 018(012)4 图象数据块相对于文件头部的偏移量 16 00 00 00(10进制=22) 0287 ' (三、BMP信息头40字节) 0288 ' 022(016)4 BMP 信息头结构长度 28 00 00 00(10进制=40) 0289 ' 026(01A)4 图像宽度 10 00 00 00 0290 ' 030(01E)4 图像高度(XOR图高度+AND图高度) 20 00 00 00 0291 ' 034(022)2 位面板数 01 00 0292 ' 036(024)2 每象素所占位数 04 00(04=16色,8=256色,18=真彩) 0293 ' 038(026)4 象素数据的压缩类型 00 00 00 00(表示未压缩) 0294 ' 042(02A)4 位图点阵的长度 C0 00 00 00(10进制=192) 0295 ' 046(02E)16 未用 16个00. 0296 ' (四、XOR位图的调色板64字节) 0297 ' 062(03E)1 蓝色分量 0298 ' 063(03F)1 绿色分量 0299 ' 064(040)1 红色分量 0300 ' 065(041)1 未用 00 0301 ' …… 0302 ' (五、XOR位图的数据128字节) 0303 ' 126(07E)128 XOR位图 0304 ' (六、单色AND位图的数据64字节) 0305 ' 254(0FE)64 AND位图 0306 ' ------------------------------------------------------------------------------------ 0307 ' 说明: 0308 ' 1.上表中有关长度的数据,遵循“低位在前,高位在后”的原则。如果有4个字节,那么后2 0309 ' 个字节为高位,前2个字节为低位,并且每2个字节内也是“低位在前,高位在后”。例如 0310 ' 偏移量为00E的图象数据块的长度是28 01 00 00,在计算时要把它们反过来,变成00 00 0311 ' 01 28,实际就是16进制的128即10进制的296;再如12 34 56 78,那么实际计算时就是: 0312 ' 78 56 34 12,即10进制的2018915346 0313 ' 2.偏移量为024的“每象素所占位数”是指象素在XOR位图中所占的字节位数(1个字节=8位) 0314 ' ,04表示每个象素占4位,换言之,就是说XOR位图中每个字节可表示2个象素。该数据如为 0315 ' 01 00,则表示单色(黑白位图),04 00为16色,08 00为256色,18 00为24位真彩。 0316 ' 3.XOR位图每字节对应2个像素(16色)或1个像素(256色),它的排列规律是:倒向(最末行的 0317 ' 像素在最前,而第一行的像素在最后,由此类推),行内像素按从左至右的顺序,字节高 0318 ' 位表示靠左的像素。AND位图每字节对应8个象素(每位对应1个象素),排列规律与XOR位 0319 ' 图相同。 0320 ' 4.真彩图标没有调色板,而是在第 3部分 BMP 信息头的后面直接存放像素的 RGB 值,24位 0321 ' 真彩图标每 3个字节对应1个像素值,其中每个字节分别对应该像素的 R、G、B值。像素的 0322 ' 排列规律与调色板模式的图标相同。 0323 ' 5.上表的第一、二、三部分中,凡字节数为1的数据,其数据类型为Byte,字节数为2的数据, 0324 ' 其数据类型为Integer,字节数为4的数据,其数据类型为Long(第三部分中有16个未用的 0325 ' 的字节,是4个Long类型的数据,它们在.bmp位图中是有作用的)。 0326 0327 ' 下面是各种图标(内含1个图像)的调色板、图像数据的长度及总长度,括号内是起始字 0328 ' 节的偏移量: 0329 ' 单位:字节 0330 ' ------------------------------------------------------ 0331 ' 图标规格 调色板 XOR位图 AND位图 总长度 0332 ' ------------------------------------------------------ 0333 ' 16 色16×16象素 (62) 64 (126) 128 (254) 64 318 0334 ' 16 色24×24象素 (62) 64 (126) 288 (414) 96 510 0335 ' 16 色32×32象素 (62) 64 (126) 512 (638) 128 766 0336 ' 16 色48×48象素 (62) 64 (126) 1152 (1278)384 1662 0337 ' 256色16×16象素 (62)1024 (1086) 256 (1342) 64 1406 0338 ' 256色24×24象素 (62)1024 (1086) 576 (1662) 96 1758 0339 ' 256色32×32象素 (62)1024 (1086)1024 (2110)128 2238 0340 ' 256色48×48象素 (62)1024 (1086)2304 (3390)384 3774 0341 ' 真 彩16×16象素 (62) 768 (830) 64 894 0342 ' 真 彩24×24象素 (62) 1728 (1790) 96 1886 0343 ' 真 彩32×32象素 (62) 3072 (3134)128 3262 0344 ' 真 彩48×48象素 (62) 6912 (6974)384 7358 0345 ' ------------------------------------------------------ 0346 ' 说明: 0347 ' 1.XOR位图的长度与图标尺寸及图标的颜色数均有关,AND位图的长度只与图标的尺寸有关, 0348 ' 与图标的颜色数无关。 0349 ' 2.XOR位图每字节对应2个像素(16色)或1个像素(256色) 0350 ' 3.AND位图每4字节为一组(这里所说的“一组”,其标准名称为“一条扫描线”,扫描线的 0351 ' 定义是:位图中的一行数据信息叫做一条扫描线),但48×48图标的 AND 位图每8个字节 0352 ' 为一组。组内每个颜色位对应1个象素。注意: 0353 ' ①16×16图标每组的后2个字节不用,所以实际上是2字节(16位)对应一行16个象素 0354 ' ②24×24图标每组的最后1个字节不用,所以实际上是3字节(24位)对应一行24个象素 0355 ' ③32×32图标每组4个字节32位对应一行32个象素 0356 ' ④48×48图标每组的后2个字节不用,所以实际上是6字节(48位)对应一行48个象素 0357 ' 4.为什么位图数据中会有不用的字节呢,这不是浪费吗?原来,Windows 有一个规定,每一 0358 ' 条扫描线必须结束于一个32位的边界,也就是说,一条扫描线的位长度(按位计算)必须 0359 ' 能整除32,或字节长度必须能整除4(XOR、AND 位图都是如此)。举例来说,如果一条扫 0360 ' 描线只有 8位,那么就要用空白的24位来补充,如果有48位,那么还必须用空白的16位来 0361 ' 补充。 0362 ' 5.XOR位图每条扫描线长度取决于两个因素:图像的宽度值和颜色数。各种颜色的图标的XOR 0363 ' 位图每条扫描线的长度如下表所示(单位:字节): 0364 0365 ' ①16色图标: 0366 ' ---------------------- 0367 ' XOR图象宽度 扫描线长度 0368 ' ---------------------- 0369 ' 16象素 8 0370 ' 17--24象素 12 0371 ' 25--32象素 16 0372 ' 33--40象素 20 0373 ' 41--48象素 24 0374 ' 49--56象素 28 0375 ' 57--64象素 32 0376 ' 65--72象素 36 0377 ' 71--80象素 40 0378 ' …… 0379 ' ---------------------- 0380 ' 可以归纳出计算公式是: 0381 ' 16色XOR位图每条扫描线长度=4×(图象宽\8+Abs((图象宽 Mod 8)>0)) 0382 0383 ' ②256色图标: 0384 ' ---------------------- 0385 ' XOR图象宽度 扫描线长度 0386 ' ---------------------- 0387 ' 16象素 16 0388 ' 17--20象素 20 0389 ' 21--24象素 24 0390 ' 25--28象素 28 0391 ' 29--32象素 32 0392 ' 33--36象素 36 0393 ' 37--40象素 40 0394 ' 41--44象素 44 0395 ' 45--48象素 48 0396 ' …… 0397 ' ---------------------- 0398 ' 可以归纳出计算公式是: 0399 ' 256色XOR位图每条扫描线长度=4×(图象宽\4+Abs((图象宽 Mod 4)>0)) 0400 0401 ' ③真彩图标: 0402 ' ---------------------- 0403 ' XOR图象宽度 扫描线长度 0404 ' ---------------------- 0405 ' 16象素 48 0406 ' 17象素 52 0407 ' 18象素 56 0408 ' 19象素 60 0409 ' 20象素 60 0410 ' 21象素 64 0411 ' 22象素 68 0412 ' 23象素 72 0413 ' 24象素 72 0414 ' …… 0415 ' ---------------------- 0416 ' 可以归纳出计算公式是: 0417 ' 真彩XOR位图每条扫描线长度=4×(图象宽×3\4+Abs((图象宽×3 Mod 4)>0)) 0418 0419 ' 6.AND位图每条扫描线的长度只与图标图像的宽度值有关。如下表所示(单位:字节): 0420 ' ---------------------- 0421 ' AND图象宽度 扫描线长度 0422 ' ---------------------- 0423 ' 16--32象素 4 0424 ' 33--64象素 8 0425 ' 65--96象素 12 0426 ' 97--128象素 16 0427 ' 129--160象素 20 0428 ' 160--192象素 24 0429 ' 192--224象素 28 0430 ' 224--255象素 32 0431 ' ---------------------- 0432 ' 可以归纳出计算公式是: 0433 ' AND位图每条扫描线长度=4×(图象宽\32+Abs((图象宽 Mod 32)>0)) 0434 0435 ' 7.要使背景透明,XOR位图的背景必须为黑色(对应的颜色位=0),图案为彩色,而 AND位 0436 ' 图则背景必须为白色(对应的颜色位=1),图案为黑色(对应的颜色位=0) 0437 ' 8.XOR位图的彩色图形信息中存储的并不是颜色值,而是与调色板对应的索引值,从 0 开始 0438 ' 编号。 0439 ' 四、图标的颜色 0440 ' 调色板模式的图标,其颜色是由调色板确定的,而调色板是可以自行定义的。比如16色 0441 ' 图标,其调色板只要有16种颜色就行。下面是以 QBasic 的16种颜色作为调色板时,XOR 位 0442 ' 图调色板的16色索引值与 QBColor 的颜色值对照: 0443 ' ---------------------------------------------------- 0444 ' 颜色 索引值 QBasic 调色板中的值(最后一个字节未用) 0445 ' ---------------------------------------------------- 0446 ' 黑色 0 0 00 00 00 00 0447 ' 深红 1 4 00 00 80 00 0448 ' 深绿 2 2 00 80 00 00 0449 ' 深黄 3 6 00 80 80 00 0450 ' 深蓝 4 1 80 00 00 00 0451 ' 深紫 5 5 80 00 80 00 0452 ' 深青 6 3 80 80 00 00 0453 ' 深灰 7 8 80 80 80 00 0454 ' 浅灰 8 7 C0 C0 C0 00 0455 ' 红色 9 C(12) 00 00 FF 00 0456 ' 绿色 A(10) A(10) 00 FF 00 00 0457 ' 黄色 B(11) E(14) 00 FF FF 00 0458 ' 蓝色 C(12) 9 FF 00 00 00 0459 ' 紫色 D(13) D(13) FF 00 FF 00 0460 ' 青色 E(14) B(11) FF FF 00 00 0461 ' 白色 F(15) F(15) FF FF FF 00 0462 ' ---------------------------------------------------- 0463 ' 怎么个对应法呢?举个例来说,比如16×16象素图标的 XOR位图中某个字节值为81,那 0464 ' 就表示该字节所对应的2个象素,左边的象素为浅灰色而右边的象素为深红色。 0465 0466 ' 五、一个具体的例子 0467 ' 有一个16色16×16象素的图标,该图标是一个边长为16、边框为红色的空心正方形,其 0468 ' 全部数据如下: 0469 ' ------------------------------------------------------ 0470 ' 偏移量 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0471 ' ------------------------------------------------------ 0472 ' 000 00 00 01 00 01 00 10 10 10 00 00 00 00 00 28 01 0473 ' 010 00 00 16 00 00 00 28 00 00 00 10 00 00 00 20 00 0474 ' 020 00 00 01 00 04 00 00 00 00 00 C0 00 00 00 00 00 0475 ' 030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0476 ' 040 00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00 0477 ' 050 00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0 0478 ' 060 C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00 0479 ' 070 00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 99 99 0480 ' 080 99 99 99 99 99 99 90 00 00 00 00 00 00 09 90 00 0481 ' 090 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0482 ' 0A0 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0483 ' 0B0 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0484 ' 0C0 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0485 ' 0D0 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0486 ' 0E0 00 00 00 00 00 09 90 00 00 00 00 00 00 09 90 00 0487 ' 0F0 00 00 00 00 00 09 99 99 99 99 99 99 99 99 00 00 0488 ' 100 00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE 0489 ' 110 00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE 0490 ' 120 00 00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE 0491 ' 130 00 00 7F FE 00 00 7F FE 00 00 00 00 00 00 0492 ' ------------------------------------------------------ 0493 0494 ' 下面对位图部分的数据加以说明: 0495 ' 1.XOR位图最末一行的数据在07E-085这8个字节中,由于是一条红线,所以索引值均为9。 0496 ' 2.XOR位图倒数第二行的数据在086-08D这8个字节中,该行的首尾2个象素为红色,其余14个 0497 ' 象素为背景色,所以086字节所对应象素的颜色索引值分别为9、0,而08D字节所对应象素 0498 ' 的颜色索引值分别为0、9,因为要屏蔽背景色,所以除了红色外,其余均为黑色,黑色在 0499 ' 调色板中的索引值为0。其余行的数据也照此分析。 0500 ' 3.AND位图最末一行的数据在0FE-101这4个字节中,后2个字节没用,前2个字节为00 00, 0501 ' 因为要屏蔽背景色,AND位图的图象位必须为0(黑色),而不管这图象原来是什么颜色, 0502 ' 所以,这一行是红线,相应的颜色位就全是0了。 0503 ' 4.AND位图倒数第二行的数据在102-105这 4个字节中,前2个字节对应该行的16个象素,其 0504 ' 值为7F FE。先看7F,其二进制为 01111111,因为该行首个象素为红色,所以对应的最高 0505 ' 位为0(黑色),跟着的7个象素都是背景色,而在AND位图中,要屏蔽背景色,那么背景色 0506 ' 的对应位应该是白色,白色在单色中表示为1,所以这8个象素所表示的16进制值就是7F了。 0507 ' 再看FE,其二进制值为 11111110,它对应的该行后8个象素,而该行最后1个象素是红色, 0508 ' 所以对应的最低位为0(黑色),其它象素是背景色,所以对应的位都是1(白色)。 0509 ' 5.其它行的数据,可以比照上述的方法自行分析。
Tags:  bmpico ico转bmp bmp是位图吗 24位bmp位图 bmp位图

延伸阅读

最新评论

发表评论