﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-c++初学者-随笔分类-图像</title><link>http://www.cppblog.com/tgh621/category/8163.html</link><description>专注技术开发</description><language>zh-cn</language><lastBuildDate>Sat, 27 Dec 2008 04:55:05 GMT</lastBuildDate><pubDate>Sat, 27 Dec 2008 04:55:05 GMT</pubDate><ttl>60</ttl><item><title>[转]PSD格式文件的读取</title><link>http://www.cppblog.com/tgh621/archive/2008/12/26/70462.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Fri, 26 Dec 2008 10:15:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/12/26/70462.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/70462.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/12/26/70462.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/70462.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/70462.html</trackback:ping><description><![CDATA[<font size=2>　PhotoShop，我想没有人会不知道吧。如今最新的版本是6.0，其图象文件*.PSD和5.5相比变化并不太大。以下我就介绍*.PSD文件的读取方法，并提供完整读取函数。其中：m_Rect为目标区域，m_lpDDS7为目标DirectDraw表面，m_pbAlphaMask为目标Aplha通告指针。Read16函数为从指定文件当前位置读取一个WORD，Read32函数为从指定文件当前位置读取一个DWORD。MAX_PSD_CHANNELS为24。以下就是*.PSD文件的读取方法，有兴趣的朋友可以继续深入研究，到时可别忘了发我一份。<br></font></font><font class=f14 id=zoom><font face=宋体><br></font></font><font face=宋体></font></font><font face=Arial><font class=f14 id=zoom><font face=宋体><font color=#99ccff><font size=2><span class=ColorCode>　　HRESULT LoadPSD( LPSTR strFilename )</span> </font><font color=#c0c0c0><span class=ColorCatchword><font size=2>// 读取PSD文件</font></span></font><font size=2><br><span class=ColorCode>　　{<br>　　　　DWORD dwWidth, dwHeight;</span> <font color=#c0c0c0><span class=ColorCatchword>// 宽高</span></font><br><span class=ColorCode>　　　　long lSurfWidth = m_Rect.right - m_Rect.left;<br>　　　　long lSurfHeight = m_Rect.bottom - m_Rect.top;<br>　　　　WORD CompressionType;</span> <font color=#c0c0c0><span class=ColorCatchword>// 压缩类型</span></font><br><span class=ColorCode>　　　　HDC hDC;<br>　　　　FILE *fpPSD;<br>　　　　WORD ChannelCount;</span> <font color=#c0c0c0><span class=ColorCatchword>// 通道数</span></font><br><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 打开PSD文件</font></span><br><span class=ColorCode>　　　　if ( ( fpPSD = fopen ( strFilename, "rb" ) ) == NULL ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 头四个字节为"8BPS"</font><br></span><span class=ColorCode>　　　　char signature[5];<br>　　　　signature[0] = fgetc( fpPSD );<br>　　　　signature[1] = fgetc( fpPSD );<br>　　　　signature[2] = fgetc( fpPSD );<br>　　　　signature[3] = fgetc( fpPSD );<br>　　　　signature[4] = '\0';<br>　　　　if ( strcmp( signature,"8BPS" ) != 0 ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 版本必须为1</font></span><br><span class=ColorCode>　　　　if ( Read16( fpPSD ) != 1 ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 跳过一些数据 (总是0)</font></span><br><span class=ColorCode>　　　　Read32( fpPSD );<br>　　　　Read16( fpPSD );<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 读取通道数</font><br></span><span class=ColorCode>　　　　ChannelCount = Read16( fpPSD );</span><br><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 确定至少有一个通道</font><br></span><span class=ColorCode>　　　　if ( ( ChannelCount &lt; 0 ) || ( ChannelCount &gt; MAX_PSD_CHANNELS ) ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 读入宽和高</font><br></span><span class=ColorCode>　　　　dwHeight = Read32( fpPSD );<br>　　　　dwWidth = Read32( fpPSD );<br>　　　　if ( dwWidth != ( DWORD )lSurfWidth ||</span> <span class=ColorCode>dwHeight != ( DWORD )lSurfHeight ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 只读入8位通道</font></span><br><span class=ColorCode>　　　　if ( Read16( fpPSD ) != 8 ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword><font color=#c0c0c0>　　　　// 确定模式为RGB.<br>　　　　// 可能值：<br>　　　　// 0: 位图<br>　　　　// 1: 灰阶<br>　　　　// 2: 索引<br>　　　　// 3: RGB<br>　　　　// 4: CMYK<br>　　　　// 7: Multichannel<br>　　　　// 8: Duotone<br>　　　　// 9: Lab</font><br></span><span class=ColorCode>　　　　if ( Read16( fpPSD ) != 3 ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 跳过数据（如调色板）</font><br></span><span class=ColorCode>　　　　int ModeDataCount = Read32( fpPSD );<br>　　　　if ( ModeDataCount )<br>　　　　　　fseek( fpPSD, ModeDataCount, SEEK_CUR );<br></span><br><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 跳过数据（如：pen tool paths, etc）</font><br></span><span class=ColorCode>　　　　int ResourceDataCount = Read32( fpPSD );<br>　　　　if ( ResourceDataCount )<br>　　　　　　fseek( fpPSD, ResourceDataCount, SEEK_CUR );<br><br></span><span class=ColorCatchword>　　　　<font color=#c0c0c0>// 条过保留数据</font><br></span><span class=ColorCode>　　　　int ReservedDataCount = Read32( fpPSD );<br>　　　　if ( ReservedDataCount )<br>　　　　　　fseek( fpPSD, ReservedDataCount, SEEK_CUR );<br></span><br><span class=ColorCatchword><font color=#c0c0c0>　　　　// 0: 非压缩<br>　　　　// 1: RLE压缩</font><br></span><span class=ColorCode>　　　　CompressionType = Read16( fpPSD );<br>　　　　if ( CompressionType &gt; 1 ) {<br>　　　　　　return E_FAIL;<br>　　　　}<br><br>　　　　BYTE* PSDPixels = new BYTE[ ( lSurfWidth * lSurfHeight ) * 4 ];<br></span><br><span class=ColorCatchword><font color=#c0c0c0>　　　　// 解包数据</font><br></span><span class=ColorCode>　　　　UnPackPSD( fpPSD, lSurfWidth, lSurfHeight, PSDPixels, ChannelCount, CompressionType );<br><br>　　　　fclose( fpPSD );<br></span><br><span class=ColorCatchword><font color=#c0c0c0>　　　　// 复制信息</font><br></span><span class=ColorCode>　　　　BITMAPINFO BitmapInfo;<br>　　　　ZeroMemory( &amp;BitmapInfo, sizeof( BitmapInfo ) );<br>　　　　BitmapInfo.bmiHeader.biSize = sizeof( BitmapInfo.bmiHeader );<br>　　　　BitmapInfo.bmiHeader.biWidth = lSurfWidth;<br>　　　　BitmapInfo.bmiHeader.biHeight = -lSurfHeight;<br>　　　　BitmapInfo.bmiHeader.biPlanes = 1;<br>　　　　BitmapInfo.bmiHeader.biBitCount = 32;<br><br>　　　　m_lpDDS7-&gt;GetDC( &amp;hDC );<br><br>　　　　int rc = StretchDIBits( hDC,<br>　　　　　　　　　　　　　　　　0,<br>　　　　　　　　　　　　　　　　0,<br>　　　　　　　　　　　　　　　　lSurfWidth,<br>　　　　　　　　　　　　　　　　lSurfHeight,<br>　　　　　　　　　　　　　　　　0,<br>　　　　　　　　　　　　　　　　0,<br>　　　　　　　　　　　　　　　　lSurfWidth,<br>　　　　　　　　　　　　　　　　lSurfHeight,<br>　　　　　　　　　　　　　　　　PSDPixels,<br>　　　　　　　　　　　　　　　　&amp;BitmapInfo,<br>　　　　　　　　　　　　　　　　DIB_RGB_COLORS,<br>　　　　　　　　　　　　　　　　SRCCOPY );<br><br>　　　　m_lpDDS7-&gt;ReleaseDC( hDC );<br><br>　　　　if ( rc == GDI_ERROR ) {<br>　　　　　　H_ARRAY_DELETE( PSDPixels );<br><br>　　#ifdef _DEBUG<br>　　　　g_pHERR-&gt;OutDebugMsg( 3, H2DSERR_INVALID_PSD );<br>　　#endif<br>　　　　return E_FAIL;<br><br>　　　　}<br><br></span></font><span class=ColorCatchword><font size=2>　　　<font color=#c0c0c0>　// 是否读取Alpha混合通道</font><br></font></span><span class=ColorCode><font size=2>　　　　if( ChannelCount &gt; 3 ) {<br>　　　　　　m_pbAlphaMask = new BYTE[ lSurfWidth * lSurfHeight ];<br><br>　　　　for ( int x = 0; x &lt; lSurfWidth; x++ )<br>　　　　　　for ( int y = 0; y &lt; lSurfHeight; y++ ) {<br>　　　　　　　　m_pbAlphaMask[ ( y * lSurfWidth ) + x ] =<br>　　　　　　　　　　　　　　 　PSDPixels[ ( ( ( y * lSurfHeight ) + x ) * 4 ) + 3 ];<br>　　　　　　}<br>　　　　}<br>　　　　else {<br>　　　　　　m_pbAlphaMask = NULL;<br>　　　　}<br><br>　　　　H_ARRAY_DELETE( PSDPixels );<br><br>　　　　return DD_OK;<br>　　}<br><br></font><span class=ColorCatchword><font size=2>　　</font><font color=#c0c0c0 size=2>// PSD文件解包</font><font size=2><br>　</font></span></span></font>
<div align=left><font color=#99ccff><span class=ColorCode><font size=2>　　void CHades2DSurface::UnPackPSD( FILE *fp,</font></span><font size=2><span class=ColorCatchword>　　　　　// fp为PSD文件指针，</span><span class=ColorCode><br>　　　　　　　　　　　　　　　　　　 DWORD dwWidth,　　 </span><span class=ColorCatchword>// dwWidth、dwHeight为宽高，</span><span class=ColorCode><br>　　　　　　　　　　　　　　　　　　 DWORD dwHeight,<br>　　　　　　　　　　　　　　　　　　 BYTE* pixels,</span><span class=ColorCatchword>　　　// pixels为解包目标指针，</span><span class=ColorCode><br>　　　　　　　　　　　　　　　　　　 WORD ChannelCnt,</span><span class=ColorCatchword>　 // ChannelCnt为通道数，</span><span class=ColorCode><br>　　　　　　　　　　　　　　　　　　 WORD Compression )</span></font><span class=ColorCatchword><font size=2> // Compression位压缩类型。 </font></span></font></div>
<div align=left><font color=#99ccff><span class=ColorCatchword><font size=2>　　　　　　　　　　　　　　　　<br>　　　　　　　　　　　　　　　　 <br></font></span><font size=2><span class=ColorCode>　　{<br>　　　　int Default[4] = { 0, 0, 0, 255 };<br>　　　　int chn[4] = { 2, 1, 0, 3};<br>　　　　int PixelCount = dwWidth * dwHeight;<br><br>　　　　if ( Compression ) {<br>　　　　　　fseek( fp, dwHeight * ChannelCnt * 2, SEEK_CUR );<br><br>　　　　　　for ( int c = 0; c &lt; 4; c++ ) {<br>　　　　　　　　int pn = 0;<br>　　　　　　　　int channel = chn[c];<br><br>　　　　　　　　if ( channel &gt;= ChannelCnt ) {<br>　　　　　　　　　　for ( pn=0; pn &lt; PixelCount ;pn++ ) {<br>　　　　　　　　　　　　pixels[ ( pn * 4 ) + channel ] = Default[ channel ];<br>　　　　　　　　　　}<br>　　　　　　　　}<br>　　　　　　　　else</span> <span class=ColorCatchword>// 非压缩<br></span></font><span class=ColorCode><font size=2>　　　　　　　　{<br>　　　　　　　　　　int count = 0;<br>　　　　　　　　　　while( count &lt; PixelCount ) {<br>　　　　　　　　　　　　int len = fgetc( fp );<br>　　　　　　　　　　　　if( len == 128 ) { }</font></span></font></div>
<div align=left><font color=#99ccff><span class=ColorCode><font size=2>　　　　　　　　　　　　else if ( len &lt; 128 )</font></span><font size=2> </font><span class=ColorCatchword><font size=2>// 非RLE</font></span></font></div>
<div align=left><font color=#99ccff><span class=ColorCode><font size=2>　　　　　　　　　　　　{<br>　　　　　　　　　　　　　　len++;<br>　　　　　　　　　　　　　　count += len;<br>　　　　　　　　　　　　　　while(len) {<br>　　　　　　　　　　　　　　　　pixels[ ( pn * 4 ) + channel ] = fgetc( fp );<br>　　　　　　　　　　　　　　　　pn++;<br>　　　　　　　　　　　　　　　　len--;<br>　　　　　　　　　　　　　　}<br>　　　　　　　　　　　　}<br>　　　 　　　　　　　　 else if ( len &gt; 128 )</font></span><font size=2> <span class=ColorCatchword>// RLE打包</span><br></font><span class=ColorCode><font size=2>　　　　　　　　　　　　{<br>　　　　　　　　　　　　　　len ^= 0x0FF;<br>　　　　　　　　　　　　　　len += 2;<br>　　　　　　　　　　　　　　unsigned char val = fgetc( fp );<br>　　　　　　　　　　　　　　count += len;<br>　　　　　　　　　　　　　　while( len ) {<br>　　　　　　　　　　　　　　　　pixels[ ( pn * 4 ) + channel ] = val;<br>　　　　　　　　　　　　　　　　pn++;<br>　　　　　　　　　　　　　　　　len--;<br>　　　　　　　　　　　　　　}<br>　　　　　　　　　　　　}<br>　　　　　　　　　　}<br>　　　　　　　　}<br>　　　　　　}<br>　　　　}<br>　　　　else<br>　　　　{<br>　　　　　　for ( int c=0; c &lt; 4; c++ ) {<br>　　　　　　　　int channel = chn[c];<br>　　　　　　　　if ( channel &gt; ChannelCnt ) {<br>　　　　　　　　　　for( int pn = 0; pn &lt; PixelCount; pn++ ) {<br>　　　　　　　　　　　　pixels[ ( pn * 4 ) + channel ] = Default[ channel ];<br>　　　　　　　　　　}<br>　　　　　　　　}<br>　　　　　　　　else {<br>　　　　　　　　　　for( int n = 0; n &lt; PixelCount; n++ ) {<br>　　　　　　　　　　　　pixels[ ( n * 4 ) + channel ] = fgetc( fp );<br>　　　　　　　　　　}<br>　　　　　　　　}<br>　　　　　　}<br>　　　　}<br>　　}</font></span></font></div>
</font></font><font face=宋体></font></font>
<img src ="http://www.cppblog.com/tgh621/aggbug/70462.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-12-26 18:15 <a href="http://www.cppblog.com/tgh621/archive/2008/12/26/70462.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]GIF文档</title><link>http://www.cppblog.com/tgh621/archive/2008/12/26/70461.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Fri, 26 Dec 2008 10:14:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/12/26/70461.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/70461.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/12/26/70461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/70461.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/70461.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.概述~~~~~~~~　　GIF(Graphics Interchange Format，图形交换格式)文件是由 CompuServe公司开发的图形文件格式，版权所有，任何商业目的使用均须 CompuServe公司授权。　　GIF图象是基于颜色列表的（存储的数据是该点的颜色对应于颜色列表的索引值），最多只支持8位（256色）。GIF文件内部分成许多存储块，用来存储多幅图象或者是决定图象表现行...&nbsp;&nbsp;<a href='http://www.cppblog.com/tgh621/archive/2008/12/26/70461.html'>阅读全文</a><img src ="http://www.cppblog.com/tgh621/aggbug/70461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-12-26 18:14 <a href="http://www.cppblog.com/tgh621/archive/2008/12/26/70461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]TGA图像文件格式资料</title><link>http://www.cppblog.com/tgh621/archive/2008/12/26/70460.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Fri, 26 Dec 2008 10:12:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/12/26/70460.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/70460.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/12/26/70460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/70460.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/70460.html</trackback:ping><description><![CDATA[<strong><font face=黑体 color=#70aab8>根据david mcduffe编写的TGA文件格式资料翻译而成<br>　</font></strong>
<pre>本文档是为满足许多对 TGA 图像格式的了解需要而创建的。本文摘录自truevision 技术指南的附录 C，如果
需要更进一步的信息，请致信以下地址：
at&amp;t
electronic photography and imaging center
2002 wellesley ave.
indianapolis, in 42619</pre>
<pre>本文档不求全面，但力求准确。如果你发现了任何拼写错误或内容错误，请告诉我，（ david mcduffe,
75530,2626 ），我将改正这些错误，谢谢。
</pre>
<pre>不全面的原因是 TGA 包含了超过六种图像文件格式，而其中的几种较为常用。 我选择了我现在使用的格式并
在本文中加以详解。 如果你需要本文中没有包含的格式说明，你可以与你的 truevision 代理商联系。</pre>
<pre>对所有的 TGA 格式的文件而言，其第三字节（二进制整数）用来区别各种不同的 TGA 文件。下面列出了该字
节表明的对应文件类型：</pre>
<pre>	0  -  文件中没有图像数据</pre>
<pre>	1  -  未压缩的，颜色表图像</pre>
<pre>	2  -  未压缩的，rgb 图像</pre>
<pre>	3  -  未压缩的，黑白图像</pre>
<pre>	9  -  runlength 编码的颜色表图像</pre>
<pre>	10 -  runlength 编码的 rgb 图像</pre>
<pre>	11 -  压缩的，黑白图像</pre>
<pre>	32 -  使用 huffman,delta 和 runlength 编码的颜色表图像</pre>
<pre>	33 -  使用 huffman,delta 和 runlength 编码的颜色映射图像，4 趟四叉树类型处理。</pre>
<pre>	本文仅仅描述对应 1，2，9 和 10 的文件格式。
</pre>
<pre>--------------------------------------------------------------------------------
|数据类型 1： 颜色表(color-mapped)图像
|--------|--------|------------------------------------------------------------
|  偏移  |  长度  |                            描述
|--------|--------|------------------------------------------------------------
|    0   |     1  |  图像信息字段（见本子表的后面）的字符数
|        |        |
|        |        |  本字段是 1 字节无符号整型，指出了图像格式区别字段长度
|        |        |  其取值范围是 0 到 255 ，当它为 0 时表示没有图像的
|        |        |  信息字段。
|        |        |
|        |        |
|--------|--------|------------------------------------------------------------
|    1   |     1  |  颜色表的类型
|        |        |
|        |        |  该字段为表示对应格式 1 的图像而包含一个二进制 1
|        |        |
|--------|--------|------------------------------------------------------------
|    2   |     1  |  图像类型码
|        |        |
|        |        |  该字段总为 1 ， 这也是此类型为格式 1 的原因
|        |        |
|--------|--------|------------------------------------------------------------
|    3   |     5  |  颜色表规格
|        |        |
|    3   |     2  |  颜色表首址
|        |        |  颜色表首元表项的整型（低位-高位）索引
|        |        |
|    5   |     2  |  颜色表的长度
|        |        |  颜色表的表项总数，整型（低位-高位）
|        |        |
|    7   |     1  |  颜色表表项的位（bit）数
|        |        |  16 代表 16 位 TGA ，24 代表 24 位 TGA ，32 代表 32 位 TGA
|        |        |
|        |        |
|--------|--------|------------------------------------------------------------
|    8   |    10  |  图像规格
|        |        |
|    8   |     2  |  图像 x 坐标起始位置
|        |        |  图像左下角 x 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   10   |     2  |  图像 y 坐标起始位置
|        |        |  图像左下角 y 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   12   |     2  |  图像宽度
|        |        |  以像素为单位，图像宽度的整型（低位-高位）值
|        |        |
|   14   |     2  |  图像高度
|        |        |  以像素为单位，图像高度的整型（低位-高位）值
|        |        |
|   16   |     1  |  图像每像素存储占用位（bit）数
|        |        |
|        |        |
|   17   |     1  |  图像描述符字节
|        |        |  bits 3-0 - 每像素的属性位（bit）数
|        |        |
|        |        |  bit 4    - 保留，必须为 0
|        |        |  bit 5    - 屏幕起始位置标志
|        |        |             0 = 原点在左下角
|        |        |             1 = 原点在左上角
|        |        |             truevision 图像必须为 0
|        |        |  bits 7-6 - 交叉数据存储标志
|        |        |             00 = 无交叉
|        |        |             01 = 两路奇/偶交叉
|        |        |             10 = 四路交叉
|        |        |             11 = 保留
|        |        |  这一项应该设为 0，不要问我为什么
|        |        |
|--------|--------|------------------------------------------------------------
|   18   |  可变  |  图像信息字段
|        |        |  包含一个自由格式的，长度是图像记录块偏移 0 处的字节中的
|        |        |  值。它常常被忽略（即偏移 0 处值为 0 ），注意其最大可以
|        |        |  含有 255 个字符。如果需要存储更多信息，可以放在图像数据
|        |        |  之后
|        |        |
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  颜色表数据
|        |        |
|        |        |  起始位置由前一个字段的大小决定；其长度由单项数据大小
|        |        |  和数据项数目决定（在前面相应的说明字段中给出）
|        |        |  每项是 2 字节，3 字节或 4 字节，字节中没有使用的位（bit）
|        |        |  被认为是属性位。
|        |        |
|        |        |  4 字节表项中，字节 1 表示 BLUE，字节 2 表示 GREEN，
|        |        |  		    字节 3 表示 RED，字节 4 表示属性
|        |        |  3 字节表项中各字节依次对应 BLUE，GREEN，RED
|        |        |
|        |        |  2 字节表项中，两个字节分解成如下形式：
|        |        |  arrrrrgg gggbbbbb
|        |        |  但是，由于低位在前，高位在后的存储顺序，从文件中读出表项
|        |        |  时，将先读入 gggbbbbb 而后读入 arrrrrgg ；a 表示属性位。
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  图像数据字段
|        |        |
|        |        |  该字段给出了 （高度）x（宽度）个颜色表项索引，每个索引
|        |        |  以整数个字节的形式存储（典型的例子如 1 或 2 个字节）
|        |        |  所有的数据都没有符号，对于 2-字节表项而言，低位字节是
|        |        |  先存储的。
|        |        |
-------------------------------------------------------------------------------
</pre>
<pre>--------------------------------------------------------------------------------
|数据类型 2： 无颜色表 rgb 图像
|--------|--------|------------------------------------------------------------
|   偏移 |   长度 |                         描述
|--------|--------|----------------------------------------------------------
|    0   |     1  |  图像信息字段（ 见本子表的后面 ）的字符数
|        |        |
|        |        |  本字段是 1 字节无符号整型，指出了图像格式区别字段长度
|        |        |  其取值范围是 0 到 255 ，当它为 0 时表示没有图像的
|        |        |  信息字段。
|        |        |
|--------|--------|------------------------------------------------------------
|    1   |     1  |  颜色表类型
|        |        |
|        |        |  该字段的内容或者为 0 或者为 1；0 表示没有颜色表，1 表示
|        |        |  颜色表存在。由于本格式是无颜色表的，因此此项通常被忽略。
|        |        |  提示：如果置为 1（targa 绘画程序）将把边框颜色设置为映射
|        |        |        中的第一种颜色
|        |        |
|--------|--------|------------------------------------------------------------
|    2   |     1  |  图像类型码
|        |        |
|        |        |  该字段总为 2 ， 这也是此类型为格式 2 的原因
|        |        |
|--------|--------|------------------------------------------------------------
|    3   |     5  |  颜色表规格
|        |        |
|        |        |  如果颜色表类型字段为 0 则被忽略；否则描述如下
|        |        |
|    3   |     2  |  颜色表首址
|        |        |  颜色表首元入口的整型（低位-高位）索引
|        |        |
|    5   |     2  |  颜色表的长度
|        |        |  颜色表的表项总数，整型（低位-高位）
|        |        |
|    7   |     1  |  颜色表表项的位（bit）数
|        |        |  16 代表 16 位 TGA ，24 代表 24 位 TGA ，32 代表 32 位 TGA
|        |        |
|        |        |
|--------|--------|------------------------------------------------------------
|    8   |    10  |  图像规格
|        |        |
|    8   |     2  |  图像 x 坐标起始位置
|        |        |  图像左下角 x 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   10   |     2  |  图像 y 坐标起始位置
|        |        |  图像左下角 y 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   12   |     2  |  图像宽度
|        |        |  以像素为单位，图像宽度的整型（低位-高位）值
|        |        |
|   14   |     2  |  图像高度
|        |        |  以像素为单位，图像高度的整型（低位-高位）值
|        |        |
|   16   |     1  |  图像每像素存储占用位（bit）数
|        |        |  它的值为16，24 或 32 等等决定了该图像是 TGA 16，TGA24
|        |        |  TGA 32 等等
|        |        |
|   17   |     1  |  图像描述符字节
|        |        |  bits 3-0 - 每像素对应的属性位的位数；对于 	TGA 16，
|        |        |             该值为 0 或 1，对于 TGA 24，该值为 0，
|        |        |             对于 TGA 32，该值为 8
|        |        |
|        |        |  bit 4    - 保留，必须为 0
|        |        |  bit 5    - 屏幕起始位置标志
|        |        |             0 = 原点在左下角
|        |        |             1 = 原点在左上角
|        |        |             对于 truevision 图像必须为 0
|        |        |  bits 7-6 - 交叉数据存储标志
|        |        |             00 = 无交叉
|        |        |             01 = 两路奇/偶交叉
|        |        |             10 = 四路交叉
|        |        |             11 = 保留
|        |        |
|--------|--------|------------------------------------------------------------
|   18   | 可变   |  图像信息字段
|        |        |  包含一个自由格式的，长度是图像记录块偏移 0 处的字节中的
|        |        |  值。它常常被忽略（即偏移 0 处值为 0 ），注意其最大可以
|        |        |  含有 255 个字符。如果需要存储更多信息，可以放在图像数据
|        |        |  之后
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  颜色表数据
|        |        |
|        |        |  如果颜色表类型为 0，则该域不存在，否则越过该域直接读取
|        |        |  图像颜色表规格中描述了每项的字节数，为 2，3，4 之一
|        |        |
|        |        |
|        |        |
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  图像数据域
|        |        |
|        |        |  这里存储了（宽度）x（高度）个像素，每个像素中的 rgb 色值
|        |        |  该色值包含整数个字节
|        |        |
|        |        |
|        |        |  3 字节表项中各字节依次对应 BLUE，GREEN，RED
|        |        |
|        |        |  2 字节表项中，两个字节分解成如下形式：
|        |        |  arrrrrgg gggbbbbb
|        |        |  但是，由于低位在前，高位在后的存储顺序，从文件中读出表项
|        |        |  时，将先读入 gggbbbbb 而后读入 arrrrrgg ；a 表示属性位
|        |        |
|        |        |  4 字节表项包含了分别代表 blue,green,red 及属性的四个
|        |        |  字节；（由于硬件上的原因）有的时候 TGA 24 类型的图像也象
|        |        |  TGA 32 类型的图像那样存储
|        |        |
|        |        |
--------------------------------------------------------------------------------
</pre>
<pre>--------------------------------------------------------------------------------
|数据类型 9:  runlength 编码，带颜色表的图像
|--------|--------|------------------------------------------------------------
|  偏移  |  长度  |                            描述
|--------|--------|------------------------------------------------------------
|    0   |     1  |  图像信息字段（见本子表的后面）的字符数
|        |        |
|        |        |  本字段是 1 字节无符号整型，指出了图像格式区别字段长度
|        |        |  其取值范围是 0 到 255 ，当它为 0 时表示没有图像的
|        |        |  信息字段。
|        |        |
|--------|--------|------------------------------------------------------------
|    1   |     1  |  颜色表的类型
|        |        |
|        |        |  该字段为表示对应带颜色表的图像而总为 1
|        |        |
|--------|--------|------------------------------------------------------------
|    2   |     1  |  图像类型码
|        |        |
|        |        |  本类型该字段为二进制 9
|        |        |
|--------|--------|------------------------------------------------------------
|    3   |     5  |  颜色表规格
|        |        |
|        |        |  如果颜色表类型字段为 0 则被忽略；否则描述如下
|        |        |
|        |        |
|    3   |     2  |  颜色表首址
|        |        |  颜色表首元入口的整型（低位-高位）索引
|        |        |
|    5   |     2  |  颜色表的长度
|        |        |  颜色表的表项总数，整型（低位-高位）
|        |        |
|    7   |     1  |  颜色表表项的位（bit）数
|        |        |  16 代表 16 位 TGA ，24 代表 24 位 TGA ，32 代表 32 位 TGA
|        |        |
|--------|--------|------------------------------------------------------------
|    8   |    10  |  图像规格
|        |        |
|    8   |     2  |  图像 x 坐标起始位置
|        |        |  图像左下角 x 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   10   |     2  |  图像 y 坐标起始位置
|        |        |  图像左下角 y 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   12   |     2  |  图像宽度
|        |        |  以像素为单位，图像宽度的整型（低位-高位）值
|        |        |
|   14   |     2  |  图像高度
|        |        |  以像素为单位，图像高度的整型（低位-高位）值
|        |        |
|   16   |     1  |  图像每像素存储占用位（bit）数
|        |        |
|        |        |
|   17   |     1  |  图像描述符字节
|        |        |  bits 3-0 - 每像素的属性位（bit）数
|        |        |
|        |        |  bit 4    - 保留，必须为 0
|        |        |  bit 5    - 屏幕起始位置标志
|        |        |             0 = 原点在左下角
|        |        |             1 = 原点在左上角
|        |        |             truevision 图像必须为 0
|        |        |  bits 7-6 - 交叉数据存储标志
|        |        |             00 = 无交叉
|        |        |             01 = 两路奇/偶交叉
|        |        |             10 = 四路交叉
|        |        |             11 = 保留
|        |        |
|--------|--------|------------------------------------------------------------
|   18   | 可变   |  图像信息字段
|        |        |  包含一个自由格式的，长度是图像记录块偏移 0 处的字节中的
|        |        |  值。它常常被忽略（即偏移 0 处值为 0 ），注意其最大可以
|        |        |  含有 255 个字符。如果需要存储更多信息，可以放在图像数据
|        |        |  之后
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  颜色表数据
|        |        |
|        |        |  起始位置由前一个字段的大小决定；其长度由单项数据大小
|        |        |  和数据项数目决定（在前面相应的说明字段中给出）
|        |        |  每项是 2 字节，3 字节或 4 字节，字节中没有使用的位（bit）
|        |        |  被认为是属性位。
|        |        |
|        |        |  4 字节表项中，字节 1 表示 BLUE，字节 2 表示 GREEN，
|        |        |  		    字节 3 表示 RED，字节 4 表示属性
|        |        |  3 字节表项中各字节依次对应 BLUE，GREEN，RED
|        |        |
|        |        |  2 字节表项中，两个字节分解成如下形式：
|        |        |  arrrrrgg gggbbbbb
|        |        |  但是，由于低位在前，高位在后的存储顺序，从文件中读出表项
|        |        |  时，将先读入 gggbbbbb 而后读入 arrrrrgg ；a 表示属性位。
|        |        |
|--------|--------|------------------------------------------------------------
| 可变   |  可变  |  图像数据域
|        |        |
|        |        |  本区域给出了（宽度）x（高度）个颜色表索引这些索引存放
|        |        |  在数据包中；有两中类型的数据包：run-length 数据包，
|        |        |  以及未加工的数据包，每种类型的数据包含有 1-字节的头信息，
|        |        |  （其中指出了数据包类型和数目），其后是可变长度的数据域
|        |        |  头信息中最高位为 1 表示 run-length 类型的数据包，当
|        |        |  它为 0 时，表示未加工的数据包
|        |        |
|        |        |  对于 run-length 数据包，头信息含义如下
|        |        |      __________________________________________________
|        |        |      | 1 bit |   7 位的重复记数减一
|        |        |      |   id  |   由于 7 位表示的最大值为 127，故最大  |
|        |        |      |       |   的运行大小为 128，（译注：原文为     |
|        |        |      |       |   the largest run size）          |
|        |        |      |-------|----------------------------------------|
|        |        |      |   1   |  c     c     c     c     c     c    c  |
|        |        |      --------------------------------------------------
|        |        |
|        |        |  对于未加工数据包，头信息的含义如下
|        |        |      __________________________________________________
|        |        |      | 1 bit |   7 位的像素个数减一                   |
|        |        |      |   id  |   由于 7 位表示的最大值为 127，故该    |
|        |        |      |       |   类型的一个数据包中像素个数不能大于   |
|        |        |      |       |   128                                  |
|        |        |      |-------|----------------------------------------|
|        |        |      |   0   |  n     n     n     n     n     n    n  |
|        |        |      --------------------------------------------------
|        |        |
|        |        |  对于 run-length 数据包而言，头信息之后是一个简单的
|        |        |  颜色索引，且假定该索引被重复头信息中低 7 位表示的次数
|        |        |  run-length 数据包也许会跨越扫描线
|        |        |  （扫描线起始于某行结束于下一行）
|        |        |
|        |        |  对于未加工的数据包，头信息之后是颜色索引（数值由头信息
|        |        |  给出）该类型的数据包也可能跨越扫描线
|        |        |
--------------------------------------------------------------------------------
</pre>
<pre>--------------------------------------------------------------------------------
|数据类型 10：run length 编码，rgb 图像
|--------|--------|------------------------------------------------------------
|   偏移 |   长度 |                         描述
|--------|--------|------------------------------------------------------------
|    0   |     1  |  图像信息字段（见本子表的后面）的字符数
|        |        |
|        |        |  本字段是 1 字节无符号整型，指出了图像格式区别字段长度
|        |        |  其取值范围是 0 到 255 ，当它为 0 时表示没有图像的
|        |        |  信息字段。
|        |        |
|--------|--------|------------------------------------------------------------
|    1   |     1  |  该字段的内容或者为 0 或者为 1；0 表示没有颜色表，1 表示
|        |        |  颜色表存在。由于本格式是无颜色表的，因此此项通常被忽略。
|        |        |  提示：如果置为 1（targa 绘画程序）将把边框颜色设置为映射
|        |        |        中的第一种颜色
|        |        |
|--------|--------|------------------------------------------------------------
|    2   |     1  |  图像类型代码
|        |        |
|        |        |  本类型该字段为二进制 10
|        |        |
|--------|--------|------------------------------------------------------------
|    3   |     5  |  颜色表规格
|        |        |
|        |        |  如果颜色表类型字段为 0 则被忽略；否则描述如下
|        |        |
|        |        |
|    3   |     2  |  颜色表首址
|        |        |  颜色表首元入口的整型（低位-高位）索引
|        |        |
|    5   |     2  |  颜色表的长度
|        |        |  颜色表的表项总数，整型（低位-高位）
|        |        |
|    7   |     1  |  颜色表表项的位（bit）数
|        |        |  16 代表 16 位 TGA ，24 代表 24 位 TGA ，32 代表 32 位 TGA
|        |        |
|--------|--------|------------------------------------------------------------
|    8   |    10  |  图像规格
|        |        |
|    8   |     2  |  图像 x 坐标起始位置
|        |        |  图像左下角 x 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   10   |     2  |  图像 y 坐标起始位置
|        |        |  图像左下角 y 坐标的整型（低位-高位）值
|        |        |
|        |        |
|   12   |     2  |  图像宽度
|        |        |  以像素为单位，图像宽度的整型（低位-高位）值
|        |        |
|   14   |     2  |  图像高度
|        |        |  以像素为单位，图像高度的整型（低位-高位）值
|        |        |
|   16   |     1  |  图像每像素存储占用位（bit）数
|        |        |
|        |        |
|   17   |     1  |  图像描述符字节
|        |        |  bits 3-0 - 每像素的属性位（bit）数
|        |        |
|        |        |  bit 4    - 保留，必须为 0
|        |        |  bit 5    - 屏幕起始位置标志
|        |        |             0 = 原点在左下角
|        |        |             1 = 原点在左上角
|        |        |             truevision 图像必须为 0
|        |        |  bits 7-6 - 交叉数据存储标志
|        |        |             00 = 无交叉
|        |        |             01 = 两路奇/偶交叉
|        |        |             10 = 四路交叉
|        |        |             11 = 保留
|        |        |
|--------|--------|------------------------------------------------------------
|   18   | 可变   |  图像信息字段
|        |        |  包含一个自由格式的，长度是图像记录块偏移 0 处的字节中的
|        |        |  值。它常常被忽略（即偏移 0 处值为 0 ），注意其最大可以
|        |        |  含有 255 个字符。如果需要存储更多信息，可以放在图像数据
|        |        |  之后
|        |        |
|--------|--------|------------------------------------------------------------
|  可变  |  可变  |  颜色表数据
|        |        |
|        |        |  如果颜色表类型为 0，则该域不存在，否则越过该域直接读取
|        |        |  图像颜色表规格中描述了每项的字节数，为 2，3，4 之一
|        |        |
|--------|--------|------------------------------------------------------------
| 可变   |  可变  |  图像数据域
|        |        |
|        |        |  本区域给出了（宽度）x（高度）个颜色表索引这些索引存放
|        |        |  在数据包中；有两中类型的数据包：run-length 数据包，
|        |        |  以及未加工的数据包，每种类型的数据包含有 1-字节的头信息，
|        |        |  （其中指出了数据包类型和数目），其后是可变长度的数据域
|        |        |  头信息中最高位为 1 表示 run-length 类型的数据包，当
|        |        |  它为 0 时，表示未加工的数据包
|        |        |
|        |        |  对于 run-length 数据包，头信息含义如下
|        |        |      __________________________________________________
|        |        |      | 1 bit |   7 位的重复记数减一
|        |        |      |   id  |   由于 7 位表示的最大值为 127，故最大  |
|        |        |      |       |   的运行大小为 128，（译注：原文为     |
|        |        |      |       |   the largest run size）          |
|        |        |      |-------|----------------------------------------|
|        |        |      |   1   |  c     c     c     c     c     c    c  |
|        |        |      --------------------------------------------------
|        |        |
|        |        |  对于未加工数据包，头信息的含义如下
|        |        |      __________________________________________________
|        |        |      | 1 bit |   7 位的像素个数减一                   |
|        |        |      |   id  |   由于 7 位表示的最大值为 127，故该    |
|        |        |      |       |   类型的一个数据包中像素个数不能大于   |
|        |        |      |       |   128                                  |
|        |        |      |-------|----------------------------------------|
|        |        |      |   0   |  n     n     n     n     n     n    n  |
|        |        |      --------------------------------------------------
|        |        |
|        |        |
|        |        |  对于 run length 数据包，头信息之后是一个简单颜色值，
|        |        |  且假定该值重复的次数为头信息中记录的数
|        |        |  run-length 数据包也许会跨越扫描线
|        |        |  （扫描线起始于某行结束于下一行）
|        |        |
|        |        |  对于未加工数据包，头信息之后是颜色值（数目由头信息指出）
|        |        |
|        |        |
|        |        |  颜色表项自身有 2-字节，3-字节或 4-字节几种大小（分别
|        |        |  对应 TGA 16,TGA 24 和 TGA 32）形式如下：
|        |        |
|        |        |
|        |        |  3 字节表项中各字节依次对应 BLUE，GREEN，RED
|        |        |
|        |        |  2 字节表项中，两个字节分解成如下形式：
|        |        |  arrrrrgg gggbbbbb
|        |        |  但是，由于低位在前，高位在后的存储顺序，从文件中读出表项
|        |        |  时，将先读入 gggbbbbb 而后读入 arrrrrgg ；a 表示属性位
|        |        |
|        |        |  4 字节表项包含了分别代表 blue,green,red 及属性的四个
|        |        |  字节；（由于硬件上的原因）有的时候 TGA 24 类型的图像也象
|        |        |  TGA 32 类型的图像那样存储
|        |        |
--------------------------------------------------------------------------------
</pre>
<img src ="http://www.cppblog.com/tgh621/aggbug/70460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-12-26 18:12 <a href="http://www.cppblog.com/tgh621/archive/2008/12/26/70460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自绘按钮补遗【转】</title><link>http://www.cppblog.com/tgh621/archive/2008/09/25/62779.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Thu, 25 Sep 2008 12:19:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/09/25/62779.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/62779.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/09/25/62779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/62779.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/62779.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/tgh621/archive/2008/09/25/62779.html'>阅读全文</a><img src ="http://www.cppblog.com/tgh621/aggbug/62779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-09-25 20:19 <a href="http://www.cppblog.com/tgh621/archive/2008/09/25/62779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PNG图像</title><link>http://www.cppblog.com/tgh621/archive/2008/09/03/60838.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Wed, 03 Sep 2008 10:34:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/09/03/60838.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/60838.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/09/03/60838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/60838.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/60838.html</trackback:ping><description><![CDATA[<p>&nbsp;J2ME平台PNG图像压缩、解压与加密技术&nbsp; 收藏新一篇: java图书资源下载 <br>在J2ME平台上PNG图片格式几乎成为了标准，无数台手持设备上运行的J2ME程序几乎都选用PNG来显示图像，包括大量的手机游戏以及手机应用，所以对PNG文件格式的了解，可以更有效的减少Jar Size，保护自有知识产权。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CoCoMo曾经对PNG文件进行过一段时间的研究，包括图像压缩、解压以及加解密等，现将研究心得记录如下： <br>PNG文件格式：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PNG文件格式分为PNG-24和PNG-8，其最大的区别是PNG-24是用24位来保存一个像素值，是真彩色，而PNG-8是用8位索引值来在调色盘中索引一个颜色，因为一个索引值的最大上限为2的8次方既128，故调色盘中颜色数最多为128种，所以该文件格式又被叫做PNG-8 128仿色。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PNG-24因为其图片容量过大，而且在Nokia和Moto等某些机型上创建图片失败和显示不正确等异常时有发生，有时还会严重拖慢显示速度，故并不常用，CoCoMo认为这些异常和平台底层的图像解压不无关系。不过该格式最大的优点是可以保存Alpha通道，同事也曾有过利用该图片格式实现Alpha混合的先例，想来随着技术的发展，手机硬件平台的提升，Alpha混合一定会被广泛的应用，到那时该格式的最大优势才会真正发挥。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PNG-8文件是目前广泛应用的PNG图像格式，其主要有六大块组成：<br>1.文件头<br>2.IHDR块<br>3.PLTE块<br>4.tRNS块<br>5.IDAT块<br>6.文件尾<br>这六大块按顺序排列，也就是说IDAT块永远是在PLTE块之后，期间也会有许多其他的区块用来描述信息，例如图像的最后修改时间是多少，图像的创建者是谁等，不过这些区块的信息对我们来说都是可有可无的描述信息，故压缩时一般先向这些区块开刀。</p>
<p>数据块：<br>除了文件头，其中四大数据块和文件尾都是由统一的数据块文件结构描述的：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk Length: 4byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk Type:&nbsp;&nbsp; 4byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk Data:&nbsp;&nbsp; Chunk Length的长度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk CRC:&nbsp;&nbsp;&nbsp; 4byte<br>例如IHDR块的数据长度为13，既<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk Length = 13 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk Type = "IHDR"</p>
<p>文件头：<br>用来标示PNG文件，为固定的64个字节：0x89504e47 0x0d0a1a0a</p>
<p>IHDR块：<br>用来描述图像的基本信息，其格式为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图像宽：&nbsp;&nbsp;&nbsp; 4byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图像高：&nbsp;&nbsp;&nbsp; 4byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图像色深： 4byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 颜色类型： 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 压缩方法： 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 滤波方法： 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 扫描方法： 1byte<br>曾经有人问过我，撒叫滤波方法和扫描方法，汗，说实话我也不知道，不过我们是在做手机游戏，不是在搞图形学不是嘛。</p>
<p>PLTE块：<br>这个就是传说中放置调色盘数据的地方啦，其格式为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 循环<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RED：&nbsp;&nbsp;&nbsp; 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GREEN：1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BLUE：&nbsp; 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END<br>循环长度嘛，不就是Chunk Length / 3的长度嘛，而且Chunk Length一定为3的倍数。</p>
<p>tRNS块：<br>这个块时有时无，主要是看你是否使用了透明色。该区块的格式为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 循环<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(对应调色盘颜色非透明)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xFF：&nbsp; 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00：&nbsp; 1byte<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END<br>循环长度为调色盘的颜色数，相当于调色盘颜色表的一个对应表，标识该颜色是否透明，0xFF不透明，0x00透明。故如果用UltraEdit查看PNG文件的二进制编码，如果看到一大片FF，一般就是tRNS区块啦，因为一个PNG文件一般只有一个透明色。</p>
<p>IDAT块：<br>这个就是存放图像数据的地方啦，这里要注意的是一个PNG文件可能有多个IDAT区块，而其他三大区块只可能有一个。<br>IDAT区块是经过压缩的，所以数据不可读，压缩算法一般为LZ77滑动窗口算法，如果硬要看里面的数据的话，用zlib库也是可以的，CoCoMo当年就见过Windows Mobile上的帝国时代巨变态的用zlib库压缩和解压该区块来进一步减少PNG文件大小，真是寸K寸金啊。</p>
<p>IEND块：<br>该区块虽然也按照数据块的结构，但Chunk Data是没有的，所以是固定的96个字节：0x00000000 0x49454e44 0xae426082</p>
<p>PNG图像压缩：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 了解了PNG的文件结构，压缩就有的放矢了。压缩有6个级别，可以根据需要选择。<br>Level1：读取PNG文件，将除六大块之外的所有区块都过滤掉<br>Level2：文件头是固定的0x89504e47 0x0d0a1a0a，文件尾是固定的0x00000000 0x49454e44 0xae426082，去掉！<br>Level3：每个区块的Chunk Type我们是否需要呢？很明显，我们自己写的压缩格式自己应该清楚是按照什么样的顺序，去掉！<br>Level4：每个区块的Chunk Length我们是否需要呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IHDR块：定长13个字节，明显不需要，去掉。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLTE块：最多128个颜色，为撒要用4byte来记录区块长度而不是用1byte来记录颜色数呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tRNS块：既然有颜色数，tRNS又是调色盘颜色表的对应表，既数量与颜色数相同，为撒还需要呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IDAT块：我想这个是唯一需要4byte来记录长度的区块。<br>Level5：每个区块的Chunk CRC是否需要呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为计算CRC需要一些时间，但对于字节较少的区块一般可以忽略不计，所以对于这个问题还是由程序员自己决定吧。对于CRC的计算可以参看CoCoMo的另一篇Blog&#8220;PNG文件的CRC码计算&#8221;<br>Level6：每个区块我们是否要原封不动的保存期数据呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IHDR块：除了宽、高、色深是需要的，后面那4byte的信息是固定的0x03000000<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLTE块：为撒要用3byte来表示RGB而不是2byte的565格式？压缩方法可以参看CoCoMo的另一篇Blog&#8220;关于PNG图像压缩的一点感悟&#8221;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tRNS块：我想tRNS块是冗余最多的区块了吧，大段大段的0xFF明显没有必要，一般的PNG文件只有一个透明色，为撒要用对应表的方法而不是一个索引来记录到底哪个是透明色呢？由于颜色数最多128，所以只需1byte就可以代替tRNS那么多0xFF啦。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IDAT块：么想法，如果你够变态，把zlib加进来吧！</p>
<p>PNG图像解压：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建了自定义的文件，J2ME端读取后，就面临解压的问题了。我们可以利用此函数来创建Image：<br>static Image<br>createImage(byte[] imageData, int imageOffset, int imageLength)<br>&nbsp;&nbsp;&nbsp;&nbsp; 前提是传入的imageData与PNG未被压缩前的一致。因为PNG文件格式是固定的，所以读取自定义的压缩文件后，开始将那些默认的数据再添加进去，实现解压的目的。下面就开始解压之旅吧!<br>首先要创建一个ByteArrayOutputStream out，<br>1.写入文件头：<br>out.writeInt(0x89504e47);<br>out.writeInt(0x0d0a1a0a);<br>2.写入IHDR块<br>out.writeInt(13);<br>out.writeInt(0x49484452);&nbsp; //0x49484452为Chunk Type "IHDR"<br>out.writeInt(width);<br>out.writeInt(height);<br>out.writeByte(depth);<br>out.writeInt(0x03000000);&nbsp; //压缩时舍掉的4byte，默认0x03000000<br>out.writeInt(crc);<br>其他区块方法一致，故略过。。。<br>3.写入文件尾<br>out.writeInt(0x00000000);<br>out.writeInt(0x49454e44);<br>out.writeInt(0xae426082);<br>4.转换成数组，创建Image<br>byte[] pngBuffer = out.toByteArray();<br>Image image = Image.createImage(pngBuffer, 0, pngBuffer.length);<br>哈哈，大功告成。这里注意如果中途数据写入有错误，经常会出现创建Image失败的异常，而且非常不好调试，不过只要自定的压缩格式定下来后，对应的创建Image的函数只要写一次，以后基本不会出问题哈。</p>
<p>PNG图像加解密：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很多人都担心自己辛苦创作的漂亮的美术图片很easy就被别人拿到了，究其原因是由于PNG文件格式是固定的，稍微了解的人用UltraEdit很容易就能找到IHDR，PLTE等标识了。CoCoMo就经常看GameLoft的图像文件，哈哈。一般是2byte的Length，然后紧接着图片数据，都放在一个文件里，直接拷贝2进制然后粘贴到一个新文件里就是一幅图。后来的加密技术会把PNG分块，例如前100个字节一块，紧接着1K一块，最后剩余字节一块，然后把块顺序打乱，用2byte来记录总长度，1byte记录顺序，但是这并没有从根本上消除IHDR，IEND这些显眼的定位标识，好像在对破解者说：嘿，看，我就在这里！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在了解了之前的压缩和解压技术，这个问题也就迎刃而解了，因为Chunk Length，Chunk Type和Chunk CRC这些东西都消失了，甚至连数据块本身的数据都修改了，我可以按照ImageWidth、ImageHeight、ImageDepth的顺序写数据，也可以倒过来写。我想再牛的PNG分析器也是无能为力的吧，唯一可以定位的就只有IDAT区块了，不过就算得到该区块的数据，也应该是一张黑白图。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不过在加解密的领域真是道高一尺，魔高一丈，CoCoMo很希望和各位共同探讨，共同提高！<br></p>
<img src ="http://www.cppblog.com/tgh621/aggbug/60838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-09-03 18:34 <a href="http://www.cppblog.com/tgh621/archive/2008/09/03/60838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转) bmp图分析</title><link>http://www.cppblog.com/tgh621/archive/2008/09/03/60837.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Wed, 03 Sep 2008 10:24:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/09/03/60837.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/60837.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/09/03/60837.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/60837.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/60837.html</trackback:ping><description><![CDATA[<p><font size=3><span>说到图片，位图（</span><font face="Times New Roman">Bitmap</font><span>）当然是最简单的，它</span><font face="Times New Roman">Windows</font><span>显示图片的基本格式，其文件扩展名为</span><font face="Times New Roman">*.BMP</font><span>。在</span><font face="Times New Roman">Windows</font><span>下，任何各式的图片文件（包括视频播放）都要转化为位图个时候才能显示出来，各种格式的图片文件也都是在位图格式的基础上采用不同的压缩算法生成的（</span><font face="Times New Roman">Flash</font><span>中使用了适量图，是按相同颜色区域存储的）。</span></font></p>
<p><font size=3><span>一、下面我们来看看位图文件（</span><font face="Times New Roman">*.BMP</font><span>）的格式。</span></font></p>
<p><font size=3><span>位图文件主要分为如下</span><font face="Times New Roman">3</font><span>个部分：</span></font></p>
<p>
<table cellSpacing=0 cellPadding=0 width=487 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=115>
            <p align=center><span><font size=3>块名称</font></span></p>
            </td>
            <td vAlign=top width=204>
            <p align=center><font size=3><span>对应</span><font face="Times New Roman">Windows</font><span>结构体定义</span></font></p>
            </td>
            <td vAlign=top width=168>
            <p align=center><font size=3><span>大小（</span><font face="Times New Roman">Byte</font><span>）</span></font></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=115>
            <p><span><font size=3>文件信息头</font></span></p>
            </td>
            <td vAlign=top width=204>
            <p><font face="Times New Roman" size=3>BITMAPFILEHEADER</font></p>
            </td>
            <td vAlign=top width=168>
            <p><font face="Times New Roman" size=3>14</font></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=115>
            <p><span><font size=3>位图信息头</font></span></p>
            </td>
            <td vAlign=top width=204>
            <p><font face="Times New Roman" size=3>BITMAPINFOHEADER</font></p>
            </td>
            <td vAlign=top width=168>
            <p><font face="Times New Roman" size=3>40</font></p>
            </td>
        </tr>
        <tr>
            <td vAlign=top width=115>
            <p><font size=3><font face="Times New Roman">RGB</font><span>颜色阵列</span></font></p>
            </td>
            <td vAlign=top width=204>
            <p><font face="Times New Roman" size=3>BYTE*</font></p>
            </td>
            <td vAlign=top width=168>
            <p><span><font size=3>由图像长宽尺寸决定</font></span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span><span>1、<span>&nbsp;&nbsp; </span></span></span><font size=3><span>文件信息头</span><font face="Times New Roman">BITMAPFILEHEADER</font></font></p>
<p><font size=3><span>结构体定义如下：</span></font></p>
<p><span><font size=3>typedef struct tagBITMAPFILEHEADER { /* bmfh */</font></span><span> </span></p>
<p><span><font size=3>UINT bfType;<span> </span></font></span><span><br></span><span><font size=3>DWORD bfSize;</font></span><span> <br></span><span><font size=3>UINT bfReserved1;</font></span><span> <br></span><span><font size=3>UINT bfReserved2;</font></span><span> <br></span><font size=3><span>DWORD bfOffBits;</span></font></p>
<p><span><font size=3>} BITMAPFILEHEADER;</font></span><span> </span></p>
<p><span><font size=3>其中：</font></span><span> </span></p>
<p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td width=139>
            <p><span><font size=3>bfType</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明文件的类型，该值必需是</span><span>0x4D42</span><span>，也就是字符</span><span>'BM'</span><span>。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>bfSize</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明该位图文件的大小，用字节为单位</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>bfReserved1</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>保留，必须设置为</span><span>0</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>bfReserved2</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>保留，必须设置为</span><span>0</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>bfOffBits</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的，因为位图信息头和调色板的长度会根据不同情况而变化，所以你可以用这个偏移值迅速的从文件中读取到位数据。</span></font></p>
            </td>
        </tr>
    </tbody>
</table>
<br></p>
<p><font size=3><span><span><font face="Times New Roman">2、</font></span></span><span>位图信息头</span><font face="Times New Roman">BITMAPINFOHEADER</font></font></p>
<p><font size=3><span>结构体定义如下：</span></font></p>
<p><span><font size=3>typedef struct tagBITMAPINFOHEADER { /* bmih */</font></span><span> </span></p>
<p><span><font size=3>DWORD biSize;</font></span><span> <br></span><span><font size=3>LONG biWidth;</font></span><span> <br></span><span><font size=3>LONG biHeight;</font></span><span> <br></span><span><font size=3>WORD biPlanes;</font></span><span> <br></span><span><font size=3>WORD biBitCount;</font></span><span> <br></span><span><font size=3>DWORD biCompression;</font></span><span> <br></span><span><font size=3>DWORD biSizeImage;</font></span><span> <br></span><span><font size=3>LONG biXPelsPerMeter;</font></span><span> <br></span><span><font size=3>LONG biYPelsPerMeter;</font></span><span> <br></span><span><font size=3>DWORD biClrUsed;</font></span><span> <br></span><font size=3><span>DWORD biClrImportant;</span></font></p>
<p><span><font size=3>} BITMAPINFOHEADER;</font></span></p>
<p><font size=3><span>其中：</span></font></p>
<p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td width=139>
            <p><span><font size=3>biSize</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明</span><font face="Times New Roman">BITMAPINFOHEADER</font><span>结构所需要的字数。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biWidth</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><span><font size=3>说明图象的宽度，以象素为单位。</font></span></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biHeight</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明图象的高度，以象素为单位。注：这个值除了用于描述图像的高度之外，它还有另一个用处，就是指明该图像是倒向的位图，还是正向的位图。如果该值是一个正数，说明图像是倒向的，如果该值是一个负数，则说明图像是正向的。大多数的</span><font face="Times New Roman">BMP</font><span>文件都是倒向的位图，也就是时，高度值是一个正数。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biPlanes</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>为目标设备说明位面数，其值将总是被设为</span><span>1</span><span>。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biBitCount</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明比特数</span><span>/</span><span>象素，其值为</span><span>1</span><span>、</span><span>4</span><span>、</span><span>8</span><span>、</span><span>16</span><span>、</span><span>24</span><span>、或</span><span>32</span><span>。但是由于我们平时用到的图像绝大部分是</span><span>24</span><span>位和</span><span>32</span><span>位的，所以我们讨论这两类图像。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biCompression</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明图象数据压缩的类型，同样我们只讨论没有压缩的类型：</span><font face="Times New Roman">BI_RGB</font><span>。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biSizeImage</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明图象的大小，以字节为单位。当用</span><font face="Times New Roman">BI_RGB</font><span>格式时，可设置为</span><font face="Times New Roman">0</font><span>。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biXPelsPerMeter</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明水平分辨率，用象素</span><font face="Times New Roman">/</font><span>米表示。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biYPelsPerMeter</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明垂直分辨率，用象素</span><font face="Times New Roman">/</font><span>米表示。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biClrUsed</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明位图实际使用的彩色表中的颜色索引数（设为</span><font face="Times New Roman">0</font><span>的话，则说明使用所有调色板项）。</span></font></p>
            </td>
        </tr>
        <tr>
            <td width=139>
            <p><span><font size=3>biClrImportant</font></span></p>
            </td>
            <td vAlign=top width=451>
            <p><font size=3><span>说明对图象显示有重要影响的颜色索引的数目，如果是</span><font face="Times New Roman">0</font><span>，表示都重要。</span></font></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><font size=3><font face="Times New Roman"><span><span>3、</span></span>RGB</font><span>颜色阵列</span></font></p>
<p><font size=3><span>有关</span><font face="Times New Roman">RGB</font><span>三色空间我想大家都很熟悉，这里我想说的是在</span><font face="Times New Roman">Windows</font><span>下，</span><font face="Times New Roman">RGB</font><span>颜色阵列存储的格式其实</span><font face="Times New Roman">BGR</font><span>。也就是说，对于</span><font face="Times New Roman">24</font><span>位的</span><font face="Times New Roman">RGB</font><span>位图像素数据格式是：</span></font></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=148>
            <p><font size=3><span>蓝色</span><font face="Times New Roman">B</font><span>值</span></font></p>
            </td>
            <td vAlign=top width=148>
            <p><font size=3><span>绿色</span><font face="Times New Roman">G</font><span>值</span></font></p>
            </td>
            <td vAlign=top width=160>
            <p><font size=3><span>红色</span><font face="Times New Roman">R</font><span>值</span></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p><font size=3><span>对于</span><font face="Times New Roman">32</font><span>位的</span><font face="Times New Roman">RGB</font><span>位图像素数据格式是：</span></font></p>
<table cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td vAlign=top width=114>
            <p><font size=3><span>蓝色</span><font face="Times New Roman">B</font><span>值</span></font></p>
            </td>
            <td vAlign=top width=114>
            <p><font size=3><span>绿色</span><font face="Times New Roman">G</font><span>值</span></font></p>
            </td>
            <td vAlign=top width=114>
            <p><font size=3><span>红色</span><font face="Times New Roman">R</font><span>值</span></font></p>
            </td>
            <td vAlign=top width=114>
            <p><font size=3><span>透明通道</span><font face="Times New Roman">A</font><span>值</span></font></p>
            </td>
        </tr>
    </tbody>
</table>
<p><font size=3><span>透明通道也称</span><font face="Times New Roman">Alpha</font><span>通道，该值是该像素点的透明属性，取值在</span><font face="Times New Roman">0</font><span>（全透明）到</span><font face="Times New Roman">255</font><span>（不透明）之间。对于</span><font face="Times New Roman">24</font><span>位的图像来说，因为没有</span><font face="Times New Roman">Alpha</font><span>通道，故整个图像都不透明。</span></font></p>
<p><span><font size=3>二、搞清了文件格式，下一步我们要实现加载。</font></span></p>
<p><font size=3><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><span>加载文件的目的是要得到图片属性，以及</span><font face="Times New Roman">RGB</font><span>数据，然后可以将其绘制在</span><font face="Times New Roman">DC</font><span>上</span><font face="Times New Roman">(GDI)</font><span>，或是生成纹理对象</span><font face="Times New Roman">(3D:OpenGL/Direct3D)</font><span>。这两种用途在数据处理上有点区别，我们主要按前一种用法讲，在和</span><font face="Times New Roman">3D</font><span>有不同的地方，我们再提出来。</span></font></p>
<p><font size=3><font face="Times New Roman">1</font><span>、加载文件头</span></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//Load the file header</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BITMAPFILEHEADER header;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;header, 0, sizeof(header));</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>inf.read((char*)&amp;header, sizeof(header));</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(header.bfType != 0x4D42)</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return false;</font></font></p>
<p><font size=3><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><span>这个很简单，没有什么好说的。</span></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>2</font><span>、加载位图信息头</span></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//Load the image information header</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BITMAPINFOHEADER infoheader;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;infoheader, 0, sizeof(infoheader));</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>inf.read((char*)&amp;infoheader, sizeof(infoheader));</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>m_iImageWidth = infoheader.biWidth;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>m_iImageHeight = infoheader.biHeight;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>m_iBitsPerPixel = infoheader.biBitCount;</font></font></p>
<p><font size=3><span><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><span>这里我们得到了</span><font face="Times New Roman">3</font><span>各重要的图形属性：宽，高，以及每个像素颜色所占用的位数。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">3、</font></span></span><span>行对齐</span></font></p>
<p><font size=3><span>由于</span><font face="Times New Roman">Windows</font><span>在进行行扫描的时候最小的单位为</span><font face="Times New Roman">4</font><span>个字节，所以当</span><font face="Times New Roman"> </font></font></p>
<p><font size=3><span>图片宽</span><font face="Times New Roman"> X </font><span>每个像素的字节数</span><span><font face="Times New Roman"> </font></span><span>！</span><font face="Times New Roman">= 4</font><span>的整数倍</span></font></p>
<p><font size=3><span>时要在每行的后面补上缺少的字节，以</span><font face="Times New Roman">0</font><span>填充（一般来说当图像宽度为</span><font face="Times New Roman">2</font><span>的幂时不需要对齐）。位图文件里的数据在写入的时候已经进行了行对齐，也就是说加载的时候不需要再做行对齐。但是这样一来图片数据的长度就不是：宽</span><font face="Times New Roman"> X </font><span>高</span><font face="Times New Roman"> X </font><span>每个像素的字节数</span><span><font face="Times New Roman"> </font></span><span>了，我们需要通过下面的方法计算正确的数据长度：</span></font></p>
<p><font face="Times New Roman" size=3>//Calculate the image data size</font></p>
<p><font face="Times New Roman" size=3>int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) &gt;&gt; 5) &lt;&lt; 2;</font></p>
<p><font face="Times New Roman" size=3>m_iImageDataSize = iLineByteCnt * m_iImageHeight;</font></p>
<p><font size=3><span><span><font face="Times New Roman">4、</font></span></span><span>加载图片数据</span></font></p>
<p><font size=3><span>对于</span><font face="Times New Roman">24</font><span>位和</span><font face="Times New Roman">32</font><span>位的位图文件，位图数据的偏移量为</span><font face="Times New Roman">sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)</font><span>，也就是说现在我们可以直接读取图像数据了。</span></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(m_pImageData) delete []m_pImageData;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>m_pImageData = new unsigned char[m_iImageDataSize];</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>inf.read((char*)m_pImageData, m_iImageDataSize);</font></font></p>
<p><font size=3><span>如果你足够细心，就会发现内存</span><font face="Times New Roman">m_pImageData</font><span>里的数据的确是</span><font face="Times New Roman">BGR</font><span>格式，可以用个纯蓝色或者是纯红色的图片测试一下。</span></font></p>
<p><font size=3><span><span><font face="Times New Roman">5、</font></span></span><span>绘制</span></font></p>
<p><font size=3><span>好了，数据和属性我们都有了，现在就可以拿来随便用了，就和吃馒头一样，爱粘白糖粘白糖，爱粘红糖粘红糖。下面是我的</span><font face="Times New Roman">GDI</font><span>绘制代码，仅作参考。</span></font></p>
<p><font face="Times New Roman" size=3>void CImage::DrawImage(HDC hdc, int iLeft, int iTop, int iWidth, int iHeight)</font></p>
<p><font face="Times New Roman" size=3>{</font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if(!hdc || m_pImageData == NULL)</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>BITMAPINFO bmi;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;bmi, 0, sizeof(bmi));</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biSize = sizeof(BITMAPINFO);</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biWidth = m_iImageWidth;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biHeight = m_iImageHeight;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biPlanes = 1;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biBitCount = m_iBitsPerPixel;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biCompression = BI_RGB;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>bmi.bmiHeader.biSizeImage = m_iImageDataSize;</font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>StretchDIBits(hdc, iLeft, iTop, iWidth, iHeight, </font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>0, 0, m_iImageWidth, m_iImageHeight, </font></font></p>
<p><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>m_pImageData, &amp;bmi, DIB_RGB_COLORS, SRCCOPY);</font></font></p>
<p><font face="Times New Roman" size=3>}</font></p>
<p><font size=3><font face="Times New Roman"><span><span>6、</span></span>3D(OpenGL)</font><span>的不同之处</span></font></p>
<p><span><font size=3>如果你是想用刚才我们得到的数据生成纹理对象，那么你还要请出下面的问题。</font></span></p>
<p><font size=3><span>首先，用来生成纹理的数据不需要对齐，也就是说不能在每行的后面加上对齐的字节。当然在</span><font face="Times New Roman">OpenGL</font><span>里要求纹理图片的尺寸为</span><font face="Times New Roman">2</font><span>的幂，所以这个问题实际上不存在；</span></font></p>
<p><font size=3><span>其次，我们得到的图形数据格式是</span><font face="Times New Roman">BGR(BGRA)</font><span>，所以在生成纹理的时候，需指定格式为</span><font face="Times New Roman">GL_BGR_EXT(GL_BGRA_EXT)</font><span>；否则需要做</span><font face="Times New Roman">BGR-&gt;RGB(BGRA-&gt;RGBA)</font><span>的转化</span></font></p>
<img src ="http://www.cppblog.com/tgh621/aggbug/60837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-09-03 18:24 <a href="http://www.cppblog.com/tgh621/archive/2008/09/03/60837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转) bmp图文件结构</title><link>http://www.cppblog.com/tgh621/archive/2008/09/03/60836.html</link><dc:creator>大海</dc:creator><author>大海</author><pubDate>Wed, 03 Sep 2008 10:22:00 GMT</pubDate><guid>http://www.cppblog.com/tgh621/archive/2008/09/03/60836.html</guid><wfw:comment>http://www.cppblog.com/tgh621/comments/60836.html</wfw:comment><comments>http://www.cppblog.com/tgh621/archive/2008/09/03/60836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tgh621/comments/commentRss/60836.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tgh621/services/trackbacks/60836.html</trackback:ping><description><![CDATA[<p align=center>位图文件可看成由4个部分组成：位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列，它具有如下所示的形式。</p>
<div align=center>
<center>
<table cellSpacing=2 borderColorDark=#000000 width=510 borderColorLight=#cc6600 border=1>
    <tbody>
        <tr>
            <td width=232>
            <p align=center>位图文件的组成</p>
            </td>
            <td width=157>
            <p align=center>结构名称</p>
            </td>
            <td width=103>
            <p align=center>符号</p>
            </td>
        </tr>
        <tr>
            <td width=232>位图文件头(bitmap-file header)</td>
            <td width=157>BITMAPFILEHEADER</td>
            <td width=103>bmfh</td>
        </tr>
        <tr>
            <td width=232>位图信息头(bitmap-information header)</td>
            <td width=157>BITMAPINFOHEADER</td>
            <td width=103>bmih</td>
        </tr>
        <tr>
            <td width=232>彩色表(color table)</td>
            <td width=157>RGBQUAD</td>
            <td width=103>aColors[]</td>
        </tr>
        <tr>
            <td width=232>图象数据阵列字节</td>
            <td width=157>BYTE</td>
            <td width=103>aBitmapBits[]</td>
        </tr>
    </tbody>
</table>
</center></div>
<p>位图文件结构可综合在表6-01中。</p>
<blockquote>
<p align=center>表01 位图文件结构内容摘要</p>
</blockquote>
<div align=center>
<center>
<table cellSpacing=2 borderColorDark=#000000 cellPadding=7 width=585 borderColorLight=#cc6600 border=1>
    <tbody>
        <tr>
            <td width=18>　</td>
            <td width=43>
            <p align=center>偏移量</p>
            </td>
            <td width=96>
            <p align=center>域的名称</p>
            </td>
            <td width=58>
            <p align=center>大小</p>
            </td>
            <td width=287>
            <p align=center>内容</p>
            </td>
        </tr>
        <tr>
            <td width=27>　
            <p>　</p>
            <p>　</p>
            <p>图象文件</p>
            <p>头</p>
            </td>
            <td width=43>0000h</td>
            <td width=80>文件标识</td>
            <td width=58>2 bytes</td>
            <td width=287>两字节的内容用来识别位图的类型：
            <p>&#8216;BM&#8217; ： Windows 3.1x, 95, NT, &#8230;</p>
            <p>&#8216;BA&#8217; ：OS/2 Bitmap Array</p>
            <p>&#8216;CI&#8217; ：OS/2 Color Icon</p>
            <p>&#8216;CP&#8217; ：OS/2 Color Pointer</p>
            <p>&#8216;IC&#8217; ： OS/2 Icon</p>
            <p>&#8216;PT&#8217; ：OS/2 Pointer</p>
            <p>注：因为OS/2系统并没有被普及开，所以在编程时，你只需判断第一个标识&#8220;BM&#8221;就行。</p>
            </td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0002h</td>
            <td width=80>File Size</td>
            <td width=58>1 dword</td>
            <td width=287>用字节表示的整个文件的大小</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0006h</td>
            <td width=80>Reserved</td>
            <td width=58>1 dword</td>
            <td width=287>保留，必须设置为0</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>000Ah</td>
            <td width=80>Bitmap Data Offset</td>
            <td width=58>1 dword</td>
            <td width=287>从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>000Eh</td>
            <td width=80>Bitmap Header Size</td>
            <td width=58>1 dword</td>
            <td width=287>位图信息头(Bitmap Info Header)的长度，用来描述位图的颜色、压缩方法等。下面的长度表示：
            <p>28h - Windows 3.1x, 95, NT, &#8230;</p>
            <p>0Ch - OS/2 1.x</p>
            <p>F0h - OS/2 2.x</p>
            <p>注：在Windows95、98、2000等<font color=#0000ff>操作系统</font>中，位图信息头的长度并不一定是28h，因为微软已经制定出了新的BMP文件格式，其中的信息头结构变化比较大，长度加长。所以最好不要直接使用常数28h，而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。</p>
            </td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0012h</td>
            <td width=80>Width</td>
            <td width=58>1 dword</td>
            <td width=287>位图的宽度，以象素为单位</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0016h</td>
            <td width=80>Height</td>
            <td width=58>1 dword</td>
            <td width=287>位图的高度，以象素为单位</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>001Ah</td>
            <td width=80>Planes</td>
            <td width=58>1 word</td>
            <td width=287>位图的位面数（注：该值将总是1）</td>
        </tr>
        <tr>
            <td width=27><br>图象
            <p>信息</p>
            <p>头</p>
            <p>　</p>
            <p>　</p>
            </td>
            <td width=43>001Ch</td>
            <td width=80>Bits Per Pixel</td>
            <td width=58>1 word</td>
            <td width=287>每个象素的位数
            <p>1 - 单色位图（实际上可有两种颜色，缺省情况下是黑色和白色。你可以自己定义这两种颜色）</p>
            <p>4 - 16 色位图</p>
            <p>8 - 256 色位图</p>
            <p>16 - 16bit 高彩色位图</p>
            <p>24 - 24bit 真彩色位图</p>
            <p>32 - 32bit 增强型真彩色位图</p>
            </td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>001Eh</td>
            <td width=80>Compression</td>
            <td width=58>1 dword</td>
            <td width=287>压缩说明：
            <p>0 - 不压缩 (使用BI_RGB表示)</p>
            <p>1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)</p>
            <p>2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)</p>
            <p>3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)</p>
            </td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0022h</td>
            <td width=80>Bitmap Data Size</td>
            <td width=58>1 dword</td>
            <td width=287>用字节数表示的位图数据的大小。该数必须是4的倍数</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0026h</td>
            <td width=80>HResolution</td>
            <td width=58>1 dword</td>
            <td width=287>用象素/米表示的水平分辨率</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>002Ah</td>
            <td width=80>VResolution</td>
            <td width=58>1 dword</td>
            <td width=287>用象素/米表示的垂直分辨率</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>002Eh</td>
            <td width=80>Colors</td>
            <td width=58>1 dword</td>
            <td width=287>位图使用的颜色数。如8-比特/象素表示为100h或者 256.</td>
        </tr>
        <tr>
            <td width=27>　</td>
            <td width=43>0032h</td>
            <td width=80>Important Colors</td>
            <td width=58>1 dword</td>
            <td width=287>指定重要的颜色数。当该域的值等于颜色数时（或者等于0时），表示所有颜色都一样重要</td>
        </tr>
        <tr>
            <td width=27>调色板数据</td>
            <td width=43>根据BMP版本的不同而不同</td>
            <td width=80>Palette</td>
            <td width=58>N * 4 byte</td>
            <td width=287>调色板规范。对于调色板中的每个表项，这4个字节用下述方法来描述RGB的值：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">1字节用于蓝色分量</td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">1字节用于绿色分量</td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">1字节用于红色分量</td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">1字节用于填充符(设置为0)</td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
        <tr>
            <td width=27>图象数据</td>
            <td width=43>根据BMP版本及调色板尺寸的不同而不同</td>
            <td width=80>Bitmap Data</td>
            <td width=58>xxx bytes</td>
            <td width=287>该域的大小取决于压缩方法及图像的尺寸和图像的位深度，它包含所有的位图数据字节，这些数据可能是彩色调色板的索引号，也可能是实际的RGB值，这将根据图像信息头中的位深度值来决定。</td>
        </tr>
    </tbody>
</table>
<br>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <blockquote>
            <p align=center>构件详解</p>
            </blockquote>
            <p>1. 位图文件头</p>
            <p>位图文件头包含有关于文件类型、文件大小、存放位置等信息，在Windows 3.0以上版本的位图文件中用BITMAPFILEHEADER结构来定义：</p>
            <p>typedef struct tagBITMAPFILEHEADER { /* bmfh */</p>
            <blockquote>UINT bfType;<br>DWORD bfSize; <br>UINT bfReserved1; <br>UINT bfReserved2; <br>DWORD bfOffBits;<br></blockquote>
            <p>} BITMAPFILEHEADER;</p>
            <p>&#160;</p>
            <p>其中： <br></p>
            <p>
            <table cellSpacing=0 width=557 border=0>
                <tbody>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bfType</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>说明文件的类型.（该值必需是0x4D42，也就是字符&#8217;BM&#8217;。我们不需要判断OS/2的位图标识，这么做现在来看似乎已经没有什么意义了，而且如果要支持OS/2的位图，程序将变得很繁琐。所以，在此只建议你检察&#8217;BM&#8217;标识） </p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bfSize</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>说明文件的大小，用字节为单位</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bfReserved1</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>保留，必须设置为0</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bfReserved2</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>保留，必须设置为0</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bfOffBits</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的，因为位图信息头和调色板的长度会根据不同情况而变化，所以你可以用这个偏移值迅速的从文件中读取到位数据。</p>
                        </blockquote></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>2. 位图信息头</p>
            <p>位图信息用BITMAPINFO结构来定义，它由位图信息头(bitmap-information header)和彩色表(color table)组成，前者用BITMAPINFOHEADER结构定义，后者用RGBQUAD结构定义。BITMAPINFO结构具有如下形式：</p>
            <p>typedef struct tagBITMAPINFO { /* bmi */</p>
            <blockquote>BITMAPINFOHEADER bmiHeader;<br>RGBQUAD bmiColors[1];<br></blockquote>
            <p>} BITMAPINFO;</p>
            <p>&#160;</p>
            <p>其中： <br></p>
            <p>
            <table cellSpacing=0 width=557 border=0>
                <tbody>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bmiHeader</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>说明BITMAPINFOHEADER结构，其中包含了有关位图的尺寸及位格式等信息</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>bmiColors</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>说明彩色表RGBQUAD结构的阵列，其中包含索引图像的真实RGB值。</p>
                        </blockquote></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>BITMAPINFOHEADER结构包含有位图文件的大小、压缩类型和颜色格式，其结构定义为：</p>
            <p>typedef struct tagBITMAPINFOHEADER { /* bmih */</p>
            <blockquote>DWORD biSize; <br>LONG biWidth; <br>LONG biHeight; <br>WORD biPlanes; <br>WORD biBitCount; <br>DWORD biCompression; <br>DWORD biSizeImage; <br>LONG biXPelsPerMeter; <br>LONG biYPelsPerMeter; <br>DWORD biClrUsed; <br>DWORD biClrImportant;<br></blockquote>
            <p>} BITMAPINFOHEADER;</p>
            <p>&#160;</p>
            <p>其中： <br></p>
            <p>
            <table cellSpacing=0 width=565 border=0>
                <tbody>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biSize</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>说明BITMAPINFOHEADER结构所需要的字数。注：这个值并不一定是BITMAPINFOHEADER结构的尺寸，它也可能是sizeof(BITMAPV4HEADER)的值，或是sizeof(BITMAPV5HEADER)的值。这要根据该位图文件的格式版本来决定，不过，就现在的情况来看，绝大多数的BMP图像都是BITMAPINFOHEADER结构的（可能是后两者太新的缘故吧:-）。</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biWidth</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>说明图象的宽度，以象素为单位</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biHeight</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>说明图象的高度，以象素为单位。注：这个值除了用于描述图像的高度之外，它还有另一个用处，就是指明该图像是倒向的位图，还是正向的位图。如果该值是一个正数，说明图像是倒向的，如果该值是一个负数，则说明图像是正向的。大多数的BMP文件都是倒向的位图，也就是时，高度值是一个正数。（注：当高度值是一个负数时（正向图像），图像将不能被压缩（也就是说biCompression成员将不能是BI_RLE8或BI_RLE4）。</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biPlanes</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>为目标设备说明位面数，其值将总是被设为1</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biBitCount</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>说明比特数/象素，其值为1、4、8、16、24、或32</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biCompression</p>
                        </blockquote></td>
                        <td width=414>说明图象数据压缩的类型。其值可以是下述值之一： <br>
                        <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                            <tbody>
                                <tr>
                                    <td vAlign=baseline width=42></td>
                                    <td vAlign=top width="100%">BI_RGB：没有压缩； <br></td>
                                </tr>
                                <tr>
                                    <td vAlign=baseline width=42></td>
                                    <td vAlign=top width="100%">BI_RLE8：每个象素8比特的RLE压缩编码，压缩格式由2字节组成(重复象素计数和颜色索引)； <br></td>
                                </tr>
                                <tr>
                                    <td vAlign=baseline width=42></td>
                                    <td vAlign=top width="100%">BI_RLE4：每个象素4比特的RLE压缩编码，压缩格式由2字节组成 <br></td>
                                </tr>
                                <tr>
                                    <td vAlign=baseline width=42></td>
                                    <td vAlign=top width="100%">BI_BITFIELDS：每个象素的比特由指定的掩码决定。<br></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biSizeImage</p>
                        </blockquote></td>
                        <td width=414>说明图象的大小，以字节为单位。当用BI_RGB格式时，可设置为0</td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biXPelsPerMeter</p>
                        </blockquote></td>
                        <td width=414>说明水平分辨率，用象素/米表示</td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biYPelsPerMeter</p>
                        </blockquote></td>
                        <td width=414>说明垂直分辨率，用象素/米表示</td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biClrUsed</p>
                        </blockquote></td>
                        <td width=414>说明位图实际使用的彩色表中的颜色索引数（设为0的话，则说明使用所有调色板项）</td>
                    </tr>
                    <tr>
                        <td width=147>
                        <blockquote>
                        <p>biClrImportant</p>
                        </blockquote></td>
                        <td width=414>
                        <blockquote>
                        <p>说明对图象显示有重要影响的颜色索引的数目，如果是0，表示都重要。</p>
                        </blockquote></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>现就BITMAPINFOHEADER结构作如下说明：</p>
            <p>(1) 彩色表的定位</p>
            <p>应用程序可使用存储在biSize成员中的信息来查找在BITMAPINFO结构中的彩色表，如下所示：</p>
            <p>pColor = ((LPSTR) pBitmapInfo + (WORD) (pBitmapInfo-&gt;bmiHeader.biSize))</p>
            <p>(2) biBitCount</p>
            <p>biBitCount=1 表示位图最多有两种颜色，缺省情况下是黑色和白色，你也可以自己定义这两种颜色。图像信息头装调色板中将有两个调色板项，称为索引0和索引1。图象数据阵列中的每一位表示一个象素。如果一个位是0，显示时就使用索引0的RGB值，如果位是1，则使用索引1的RGB值。</p>
            <p>biBitCount=4 表示位图最多有16种颜色。每个象素用4位表示，并用这4位作为彩色表的表项来查找该象素的颜色。例如，如果位图中的第一个字节为0x1F，它表示有两个象素，第一象素的颜色就在彩色表的第2表项中查找，而第二个象素的颜色就在彩色表的第16表项中查找。此时，调色板中缺省情况下会有16个RGB项。对应于索引0到索引15。</p>
            <p>biBitCount=8 表示位图最多有256种颜色。每个象素用8位表示，并用这8位作为彩色表的表项来查找该象素的颜色。例如，如果位图中的第一个字节为0x1F，这个象素的颜色就在彩色表的第32表项中查找。此时，缺省情况下，调色板中会有256个RGB项，对应于索引0到索引255。</p>
            <p>biBitCount=16 表示位图最多有216种颜色。每个色素用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。你在读取一个像素之后，可以分别用掩码&#8220;与&#8221;上像素值，从而提取出想要的颜色分量（当然还要再经过适当的左右移操作）。在NT系统中，则没有格式限制，只不过要求掩码之间不能有重叠。（注：这种格式的图像使用起来是比较麻烦的，不过因为它的显示效果接近于真彩，而图像数据又比真彩图像小的多，所以，它更多的被用于游戏软件）。</p>
            <p>biBitCount=24 表示位图最多有224种颜色。这种位图没有调色板（bmiColors成员尺寸为0），在位数组中，每3个字节代表一个象素，分别对应于颜色R、G、B。</p>
            <p>biBitCount=32 表示位图最多有232种颜色。这种位图的结构与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对齐的，所以在内存中进行图像处理时可进行汇编级的代码优化（简单））。</p>
            <p>(3) ClrUsed</p>
            <p>BITMAPINFOHEADER结构中的成员ClrUsed指定实际使用的颜色数目。如果ClrUsed设置成0，位图使用的颜色数目就等于biBitCount成员中的数目。请注意，如果ClrUsed的值不是可用颜色的最大值或不是0，则在编程时应该注意调色板尺寸的计算，比如在4位位图中，调色板的缺省尺寸应该是16＊sizeof(RGBQUAD)，但是，如果ClrUsed的值不是16或者不是0，那么调色板的尺寸就应该是ClrUsed＊sizeof(RGBQUAD)。</p>
            <p>(4) 图象数据压缩</p>
            <p>① BI_RLE8：每个象素为8比特的RLE压缩编码，可使用编码方式和绝对方式中的任何一种进行压缩，这两种方式可在同一幅图中的任何地方使用。</p>
            <p>编码方式：由2个字节组成，第一个字节指定使用相同颜色的象素数目，第二个字节指定使用的颜色索引。此外，这个字节对中的第一个字节可设置为0，联合使用第二个字节的值表示：</p>
            <p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为0：行的结束。 <br></td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为1：图象结束。 <br></td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为2：其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。 <br></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>绝对方式：第一个字节设置为0，而第二个字节设置为0x03～0xFF之间的一个值。在这种方式中，第二个字节表示跟在这个字节后面的字节数，每个字节包含单个象素的颜色索引。压缩数据格式需要字边界(word boundary)对齐。下面的例子是用16进制表示的8-位压缩图象数据：</p>
            <p align=center>03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01 02 78 00 00 09 1E 00 01 <br>这些压缩数据可解释为 ：</p>
            <div align=center>
            <center>
            <table cellSpacing=2 borderColorDark=#000000 width=443 borderColorLight=#cc6600 border=1>
                <tbody>
                    <tr>
                        <td width=143>
                        <p align=center>压缩数据 </p>
                        </td>
                        <td width=288>
                        <p align=center>扩展数据</p>
                        </td>
                    </tr>
                    <tr>
                        <td width=143>03 04</td>
                        <td width=288>04 04 04 </td>
                    </tr>
                    <tr>
                        <td width=143>05 06</td>
                        <td width=288>06 06 06 06 06 </td>
                    </tr>
                    <tr>
                        <td width=143>00 03 45 56 67 00</td>
                        <td width=288>45 56 67 </td>
                    </tr>
                    <tr>
                        <td width=143>02 78</td>
                        <td width=288>78 78 </td>
                    </tr>
                    <tr>
                        <td width=143>00 02 05 01</td>
                        <td width=288>从当前位置右移5个位置后向下移一行</td>
                    </tr>
                    <tr>
                        <td width=143>02 78</td>
                        <td width=288>78 78 </td>
                    </tr>
                    <tr>
                        <td width=143>00 00</td>
                        <td width=288>行结束</td>
                    </tr>
                    <tr>
                        <td width=143>09 1E</td>
                        <td width=288>1E 1E 1E 1E 1E 1E 1E 1E 1E </td>
                    </tr>
                    <tr>
                        <td width=143>00 01</td>
                        <td width=288>RLE编码图象结束 </td>
                    </tr>
                </tbody>
            </table>
            </center></div>
            <p>② BI_RLE4：每个象素为4比特的RLE压缩编码，同样也可使用编码方式和绝对方式中的任何一种进行压缩，这两种方式也可在同一幅图中的任何地方使用。这两种方式是：</p>
            <p>编码方式：由2个字节组成，第一个字节指定象素数目，第二个字节包含两种颜色索引，一个在高4位，另一个在低4位。第一个象素使用高4位的颜色索引，第二个使用低4位的颜色索引，第3个使用高4位的颜色索引，依此类推。</p>
            <p>绝对方式：这个字节对中的第一个字节设置为0，第二个字节包含有颜色索引数，其后续字节包含有颜色索引，颜色索引存放在该字节的高、低4位中，一个颜色索引对应一个象素。此外，BI_RLE4也同样联合使用第二个字节中的值表示：</p>
            <p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为0：行的结束。 <br></td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为1：图象结束。 <br></td>
                    </tr>
                    <tr>
                        <td vAlign=baseline width=42><img height=20 hspace=11 src="http://cnxhacker.net/editor/UploadFile/2005-9/15/200591510910917.gif" width=20></td>
                        <td vAlign=top width="100%">第二个字节的值为2：其后的两个字节表示下一个象素从当前开始的水平和垂直位置的偏移量。 <br></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>下面的例子是用16进制数表示的4-位压缩图象数据：</p>
            <p>03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01 04 78 00 00 09 1E 00 01</p>
            <p align=center>这些压缩数据可解释为 ：</p>
            <div align=center>
            <center>
            <table cellSpacing=2 borderColorDark=#000000 width=417 borderColorLight=#cc6600 border=1>
                <tbody>
                    <tr>
                        <td width=141>
                        <p align=center>压缩数据</p>
                        </td>
                        <td width=264>
                        <p align=center>扩展数据</p>
                        </td>
                    </tr>
                    <tr>
                        <td width=141>03 04</td>
                        <td width=264>0 4 0</td>
                    </tr>
                    <tr>
                        <td width=141>05 06</td>
                        <td width=264>0 6 0 6 0 </td>
                    </tr>
                    <tr>
                        <td width=141>00 06 45 56 67 00</td>
                        <td width=264>4 5 5 6 6 7 </td>
                    </tr>
                    <tr>
                        <td width=141>04 78</td>
                        <td width=264>7 8 7 8 </td>
                    </tr>
                    <tr>
                        <td width=141>00 02 05 01</td>
                        <td width=264>从当前位置右移5个位置后向下移一行</td>
                    </tr>
                    <tr>
                        <td width=141>04 78</td>
                        <td width=264>7 8 7 8 </td>
                    </tr>
                    <tr>
                        <td width=141>00 00</td>
                        <td width=264>行结束</td>
                    </tr>
                    <tr>
                        <td width=141>09 1E</td>
                        <td width=264>1 E 1 E 1 E 1 E 1 </td>
                    </tr>
                    <tr>
                        <td width=141>00 01</td>
                        <td width=264>RLE图象结束 </td>
                    </tr>
                </tbody>
            </table>
            </center></div>
            <p>3. 彩色表</p>
            <p>彩色表包含的元素与位图所具有的颜色数相同，象素的颜色用RGBQUAD结构来定义。对于24-位真彩色图象就不使用彩色表（同样也包括16位、和32位位图），因为位图中的RGB值就代表了每个象素难丈 ２噬 碇械难丈 囱丈 闹匾 耘判颍 饪梢愿ㄖ 允厩 绦蛭 荒芟允咀愎欢嘌丈 南允旧璞赶允静噬 枷蟆 GBQUAD结构描述由R、G、B相对强度组成的颜色，定义如下：</p>
            <p>typedef struct tagRGBQUAD { /* rgbq */</p>
            <blockquote>BYTE rgbBlue; <br>BYTE rgbGreen; <br>BYTE rgbRed; <br>BYTE rgbReserved;<br></blockquote>
            <p>} RGBQUAD;</p>
            <p>&#160;</p>
            <p>其中： <br></p>
            <p>
            <table cellSpacing=0 width=557 border=0>
                <tbody>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>rgbBlue</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>指定蓝色强度</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>rgbGreen</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>指定绿色强度</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>rgbRed</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>指定红色强度</p>
                        </blockquote></td>
                    </tr>
                    <tr>
                        <td width="22%">
                        <blockquote>
                        <p>rgbReserved</p>
                        </blockquote></td>
                        <td width="78%">
                        <blockquote>
                        <p>保留，设置为0</p>
                        </blockquote></td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>4. 位图数据</p>
            <p align=center>紧跟在彩色表之后的是图象数据字节阵列。图象的每一扫描行由表示图象象素的连续的字节组成，每一行的字节数取决于图象的颜色数目和用象素表示的图象宽度。扫描行是由底向上存储的，这就是说，阵列中的第一个字节表示位图左下角的象素，而最后一个字节表示位图右上角的象素。（只针对与倒向DIB，如果是正向DIB，则扫描行是由顶向下存储的），倒向DIB的原点在图像的左下角，而正向DIB的原点在图像的左上角。同时，每一扫描行的字节数必需是4的整倍数，也就是DWORD对齐的。如果你想确保图像的扫描行DWORD对齐，可使用下面的代码：<br><br>(((width*biBitCount)+31)&gt;&gt;5)&lt;&lt;2</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</center></div>
<img src ="http://www.cppblog.com/tgh621/aggbug/60836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tgh621/" target="_blank">大海</a> 2008-09-03 18:22 <a href="http://www.cppblog.com/tgh621/archive/2008/09/03/60836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>