📄 bmp_fileformat.htm
字号:
<p><font size="+0">应用程序可使用存储在biSize成员中的信息来查找在BITMAPINFO结构中的彩色表,如下所示:</font>
</p>
<p><font size="+0">pColor = ((LPSTR) pBitmapInfo + (WORD)
(pBitmapInfo->bmiHeader.biSize))</font> </p>
<p><b><font size="+0">(2) biBitCount</font></b> </p>
<p><font size="+0"><b>biBitCount=1 </b>表示位图最多有两种颜色,缺省情况下是黑色和白色,你也可以自己定义这两种颜色。图像信息头装调色板中将有两个调色板项,称为索引0和索引1。图象数据阵列中的每一位表示一个象素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1的RGB值。</font>
</p>
<p><font size="+0"><b>biBitCount=4 </b>表示位图最多有16种颜色。每个象素用4位表示,并用这4位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,它表示有两个象素,第一象素的颜色就在彩色表的第2表项中查找,而第二个象素的颜色就在彩色表的第16表项中查找。此时,调色板中缺省情况下会有16个RGB项。对应于索引0到索引15。</font>
</p>
<p><font size="+0"><b>biBitCount=8 </b>表示位图最多有256种颜色。每个象素用8位表示,并用这8位作为彩色表的表项来查找该象素的颜色。例如,如果位图中的第一个字节为0x1F,这个象素的颜色就在彩色表的第32表项中查找。此时,缺省情况下,调色板中会有256个RGB项,对应于索引0到索引255。</font>
</p>
<p><font size="+0"><b>biBitCount=16 </b>表示位图最多有2<sup>16</sup>种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。</font>
</p>
<p><font size="+0"><b>biBitCount=24 </b>表示位图最多有2<sup>24</sup>种颜色。这种位图没有调色板(bmiColors成员尺寸为0),在位数组中,每3个字节代表一个象素,分别对应于颜色R、G、B。</font>
</p>
<p><font size="+0"><b>biBitCount=32 </b>表示位图最多有2<sup>32</sup>种颜色。这种位图的结构与16位位图结构非常类似,当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最高位—保留,红8位、绿8位、蓝8位。这种格式也被成为888 32位图。如果 biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or 98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。(注:这种图像格式比较规整,因为它是DWORD对齐的,所以在内存中进行图像处理时可进行汇编级的代码优化(简单))。</font>
</p>
<p><b><font size="+0">(3) ClrUsed</font></b> </p>
<p><font size="+0">BITMAPINFOHEADER结构中的成员ClrUsed指定实际使用的颜色数目。如果ClrUsed设置成0,位图使用的颜色数目就等于biBitCount成员中的数目。请注意,如果ClrUsed的值不是可用颜色的最大值或不是0,则在编程时应该注意调色板尺寸的计算,比如在4位位图中,调色板的缺省尺寸应该是16*sizeof(RGBQUAD),但是,如果ClrUsed的值不是16或者不是0,那么调色板的尺寸就应该是ClrUsed*sizeof(RGBQUAD)。</font>
</p>
<p><b><font size="+0">(4) 图象数据压缩</font></b> </p>
<p><font size="+0"><b>① BI_RLE8:</b>每个象素为8比特的RLE压缩编码,可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式可在同一幅图中的任何地方使用。</font>
</p>
<p><font size="+0"><b>编码方式</b>:由2个字节组成,第一个字节指定使用相同颜色的象素数目,第二个字节指定使用的颜色索引。此外,这个字节对中的第一个字节可设置为0,联合使用第二个字节的值表示:</font>
<br>
</p>
<!--msthemelist--><table border="0" cellpadding="0" cellspacing="0" width="100%">
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为0:行的结束。 <br>
<!--msthemelist--></td></tr>
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为1:图象结束。 <br>
<!--msthemelist--></td></tr>
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为2:其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。
<br>
<!--msthemelist--></td></tr>
<!--msthemelist--></table>
<p><font size="+0"><b>绝对方式</b>:第一个字节设置为0,而第二个字节设置为0x03~0xFF之间的一个值。在这种方式中,第二个字节表示跟在这个字节后面的字节数,每个字节包含单个象素的颜色索引。压缩数据格式需要字边界(word
boundary)对齐。下面的例子是用16进制表示的8-位压缩图象数据:</font> </p>
<p align="center"><font size="+0">03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01 02 78 00
00 09 1E 00 01</font> <br>
<font size="+0">这些压缩数据可解释为 :</font> </p>
<div align="center"><center>
<table BORDER="1" CELLSPACING="2" WIDTH="443" bordercolordark="#000000" bordercolorlight="#CC6600">
<tr>
<td WIDTH="143"><p align="center"><font size="+0">压缩数据 </font> </td>
<td WIDTH="288"><p align="center"><font size="+0">扩展数据</font> </td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">03 04</font></td>
<td WIDTH="288"><font size="+0">04 04 04 </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">05 06</font></td>
<td WIDTH="288"><font size="+0">06 06 06 06 06 </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">00 03 45 56 67 00</font></td>
<td WIDTH="288"><font size="+0">45 56 67 </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">02 78</font></td>
<td WIDTH="288"><font size="+0">78 78 </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">00 02 05 01</font></td>
<td WIDTH="288"><font size="+0">从当前位置右移5个位置后向下移一行</font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">02 78</font></td>
<td WIDTH="288"><font size="+0">78 78 </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">00 00</font></td>
<td WIDTH="288"><font size="+0">行结束</font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">09 1E</font></td>
<td WIDTH="288"><font size="+0">1E 1E 1E 1E 1E 1E 1E 1E 1E </font></td>
</tr>
<tr>
<td WIDTH="143"><font size="+0">00 01</font></td>
<td WIDTH="288"><font size="+0">RLE编码图象结束 </font></td>
</tr>
</table>
</center></div><font size="+0"><b>
<p>② BI_RLE4:</b>每个象素为4比特的RLE压缩编码,同样也可使用编码方式和绝对方式中的任何一种进行压缩,这两种方式也可在同一幅图中的任何地方使用。这两种方式是:</font>
</p>
<p><font size="+0">编码方式:由2个字节组成,第一个字节指定象素数目,第二个字节包含两种颜色索引,一个在高4位,另一个在低4位。第一个象素使用高4位的颜色索引,第二个使用低4位的颜色索引,第3个使用高4位的颜色索引,依此类推。</font>
</p>
<p><font size="+0">绝对方式:这个字节对中的第一个字节设置为0,第二个字节包含有颜色索引数,其后续字节包含有颜色索引,颜色索引存放在该字节的高、低4位中,一个颜色索引对应一个象素。此外,BI_RLE4也同样联合使用第二个字节中的值表示:</font>
<br>
</p>
<!--msthemelist--><table border="0" cellpadding="0" cellspacing="0" width="100%">
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为0:行的结束。 <br>
<!--msthemelist--></td></tr>
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为1:图象结束。 <br>
<!--msthemelist--></td></tr>
<!--msthemelist--><tr><td valign="baseline" width="42"><img src="urbbul1a.gif" width="20" height="20" hspace="11"></td><td valign="top" width="100%">第二个字节的值为2:其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。
<br>
<!--msthemelist--></td></tr>
<!--msthemelist--></table>
<p><font size="+0">下面的例子是用16进制数表示的4-位压缩图象数据:</font>
</p>
<p><font size="+0">03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01 04 78 00 00 09 1E 00 01</font>
</p>
<p align="center"><font size="+0">这些压缩数据可解释为 :</font> </p>
<div align="center"><center>
<table BORDER="1" CELLSPACING="2" WIDTH="417" bordercolordark="#000000" bordercolorlight="#CC6600">
<tr>
<td WIDTH="141"><p align="center"><font size="+0">压缩数据</font> </td>
<td WIDTH="264"><p align="center"><font size="+0">扩展数据</font> </td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">03 04</font></td>
<td WIDTH="264"><font size="+0">0 4 0</font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">05 06</font></td>
<td WIDTH="264"><font size="+0">0 6 0 6 0 </font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">00 06 45 56 67 00</font></td>
<td WIDTH="264"><font size="+0">4 5 5 6 6 7 </font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">04 78</font></td>
<td WIDTH="264"><font size="+0">7 8 7 8 </font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">00 02 05 01</font></td>
<td WIDTH="264"><font size="+0">从当前位置右移5个位置后向下移一行</font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">04 78</font></td>
<td WIDTH="264"><font size="+0">7 8 7 8 </font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">00 00</font></td>
<td WIDTH="264"><font size="+0">行结束</font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">09 1E</font></td>
<td WIDTH="264"><font size="+0">1 E 1 E 1 E 1 E 1 </font></td>
</tr>
<tr>
<td WIDTH="141"><font size="+0">00 01</font></td>
<td WIDTH="264"><font size="+0">RLE图象结束 </font></td>
</tr>
</table>
</center></div><font size="+0" color="#7F007F"><b>
<p>3. 彩色表</b></font> </p>
<p><font size="+0">彩色表包含的元素与位图所具有的颜色数相同,象素的颜色用RGBQUAD结构来定义。对于24-位真彩色图象就不使用彩色表(同样也包括16位、和32位位图),因为位图中的RGB值就代表了每个象素的颜色。彩色表中的颜色按颜色的重要性排序,这可以辅助显示驱动程序为不能显示足够多颜色数的显示设备显示彩色图象。RGBQUAD结构描述由R、G、B相对强度组成的颜色,定义如下:</font>
</p>
<p><font size="+0">typedef struct tagRGBQUAD { /* rgbq */</font>
<blockquote>
<font size="+0">BYTE rgbBlue;</font> <br>
<font size="+0">BYTE rgbGreen;</font> <br>
<font size="+0">BYTE rgbRed;</font> <br>
<font size="+0">BYTE rgbReserved;</font><br>
</blockquote>
<font size="+0">
} RGBQUAD;</font> </p>
<p><font size="+0">其中:</font> <br>
</p>
<table BORDER="0" CELLSPACING="0" WIDTH="557">
<tr>
<td WIDTH="22%"><blockquote>
<font size="+0"><p>rgbBlue</font></p>
</blockquote>
</td>
<td WIDTH="78%"><blockquote>
<font size="+0"><p>指定蓝色强度</font></p>
</blockquote>
</td>
</tr>
<tr>
<td WIDTH="22%"><blockquote>
<font size="+0"><p>rgbGreen</font></p>
</blockquote>
</td>
<td WIDTH="78%"><blockquote>
<font size="+0"><p>指定绿色强度</font></p>
</blockquote>
</td>
</tr>
<tr>
<td WIDTH="22%"><blockquote>
<font size="+0"><p>rgbRed</font></p>
</blockquote>
</td>
<td WIDTH="78%"><blockquote>
<font size="+0"><p>指定红色强度</font></p>
</blockquote>
</td>
</tr>
<tr>
<td WIDTH="22%"><blockquote>
<font size="+0"><p>rgbReserved</font></p>
</blockquote>
</td>
<td WIDTH="78%"><blockquote>
<font size="+0"><p>保留,设置为0</font></p>
</blockquote>
</td>
</tr>
</table>
<p><font size="+0" color="#7F007F"><b>4. 位图数据</b></font> </p>
<p align="center"><font size="+0">紧跟在彩色表之后的是图象数据字节阵列。图象的每一扫描行由表示图象象素的连续的字节组成,每一行的字节数取决于图象的颜色数目和用象素表示的图象宽度。扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。(只针对与倒向DIB,如果是正向DIB,则扫描行是由顶向下存储的),倒向DIB的原点在图像的左下角,而正向DIB的原点在图像的左上角。同时,每一扫描行的字节数必需是4的整倍数,也就是DWORD对齐的。如果你想确保图像的扫描行DWORD对齐,可使用下面的代码:<br>
<br>(((width*biBitCount)+31)>>5)<<2<br><br></font>
</p>
<p><font size="+0" color="#7F007F"><b>5. 参考书目</b></font> </p>
<p align="left"><font size="+0">
《图象文件格式(上、下)—Windows编程》<br>
《图像文件格式大全》<br>
《Programming Windows by Charles Petzold》<br>
</font></p>
<p><font size="+0" color="#7F007F"><b>6. 相关站点</b></font> </p>
<p align="left"><font size="+0">
各种格式:http://www.wotsit.org/<br>
各种格式:http://www.csdn.net/<br>
位图格式:http://www.cica.indiana.edu/graphics/image_specs/bmp.format.txt<br>
<br>
〈完〉<br>YZ 2000-8-13 13:11<br>
</font></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -