⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csdn_文档中心_bmp位图文件结构及vc操作.htm

📁 csdn10年中间经典帖子
💻 HTM
📖 第 1 页 / 共 2 页
字号:
        <TR>
          <TD align=middle height=10></TD>
          <TD height=10></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
      <TABLE border=0 width=600>
        <TBODY>
        <TR>
          <TD align=left><BR>
            <DIV align=center><FONT size=2><B><FONT 
            size=3></FONT></B></FONT>&nbsp;</DIV>
            <DIV align=right>&nbsp;</DIV><BR>
            <DIV><!--jcstart-->浙江工业大学 朱永辉<BR><BR>---- 
            用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数显示BMP位图,可以消除以上的缺点。 
            <BR><BR>---- 一、BMP文件结构 <BR><BR>---- 1. BMP文件组成 <BR><BR>---- 
            BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 <BR><BR>---- 2. BMP文件头 <BR><BR>---- 
            BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 <BR><BR>---- 其结构定义如下: 
            <BR><BR>typedef struct tagBITMAPFILEHEADER<BR>{<BR>WORDbfType; // 
            位图文件的类型,必须为BM<BR>DWORD bfSize; // 位图文件的大小,以字节为单位<BR>WORDbfReserved1; 
            // 位图文件保留字,必须为0<BR>WORDbfReserved2; // 位图文件保留字,必须为0<BR>DWORD 
            bfOffBits; // 位图数据的起始位置,以相对于位图<BR>// 文件头的偏移量表示,以字节为单位<BR>} 
            BITMAPFILEHEADER;<BR><BR>---- 3. 位图信息头 
            <BR><BR>BMP位图信息头数据用于说明位图的尺寸等信息。<BR>typedef struct 
            tagBITMAPINFOHEADER{<BR>DWORD biSize; // 本结构所占用字节数<BR>LONGbiWidth; 
            // 位图的宽度,以像素为单位<BR>LONGbiHeight; // 位图的高度,以像素为单位<BR>WORD biPlanes; 
            // 目标设备的级别,必须为1<BR>WORD biBitCount// 每个像素所需的位数,必须是1(双色),<BR>// 
            4(16色),8(256色)或24(真彩色)之一<BR>DWORD biCompression; // 位图压缩类型,必须是 
            0(不压缩),<BR>// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一<BR>DWORD biSizeImage; 
            // 位图的大小,以字节为单位<BR>LONGbiXPelsPerMeter; // 
            位图水平分辨率,每米像素数<BR>LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数<BR>DWORD 
            biClrUsed;// 位图实际使用的颜色表中的颜色数<BR>DWORD biClrImportant;// 
            位图显示过程中重要的颜色数<BR>} BITMAPINFOHEADER;<BR><BR>---- 4. 颜色表 <BR><BR>---- 
            颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: 
            <BR><BR>typedef struct tagRGBQUAD {<BR>BYTErgbBlue;// 
            蓝色的亮度(值范围为0-255)<BR>BYTErgbGreen; // 绿色的亮度(值范围为0-255)<BR>BYTErgbRed; 
            // 红色的亮度(值范围为0-255)<BR>BYTErgbReserved;// 保留,必须为0<BR>} 
            RGBQUAD;<BR>颜色表中RGBQUAD结构数据的个数有biBitCount来确定:<BR>当biBitCount=1,4,8时,分别有2,16,256个表项;<BR>当biBitCount=24时,没有颜色表项。<BR>位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:<BR>typedef 
            struct tagBITMAPINFO {<BR>BITMAPINFOHEADER bmiHeader; // 
            位图信息头<BR>RGBQUAD bmiColors[1]; // 颜色表<BR>} BITMAPINFO;<BR><BR>---- 
            5. 位图数据 <BR><BR>---- 
            位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 
            <BR><BR>当biBitCount=1时,8个像素占1个字节;<BR>当biBitCount=4时,2个像素占1个字节;<BR>当biBitCount=8时,1个像素占1个字节;<BR>当biBitCount=24时,1个像素占3个字节;<BR><BR>Windows规定一个扫描行所占的字节数必须是 
            4的倍数(即以long为单位),不足的以0填充, <BR><BR>一个扫描行所占的字节数计算方法: DataSizePerLine= 
            (biWidth* biBitCount+31)/8; <BR><BR>// 一个扫描行所占的字节数 DataSizePerLine= 
            DataSizePerLine/4*4; // 字节数必须是4的倍数 <BR><BR>位图数据的大小(不压缩情况下): 
            DataSize= DataSizePerLine* biHeight; <BR><BR>---- 二、BMP位图一般显示方法 
            <BR><BR>---- 1. 申请内存空间用于存放位图文件 <BR><BR>---- 
            GlobalAlloc(GHND,FileLength); <BR><BR>---- 2. 位图文件读入所申请内存空间中 
            <BR><BR>---- LoadFileToMemory( mpBitsSrc,mFileName); <BR><BR>---- 3. 
            在OnPaint等函数中用创建显示用位图 <BR><BR>---- 
            用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容DC, <BR><BR>---- 
            用SelectBitmap()选择显示位图。 <BR><BR>---- 4. 用BitBlt或StretchBlt等函数显示位图 
            <BR><BR>---- 5. 用DeleteObject()删除所创建的位图 <BR><BR>---- 以上方法的缺点是: 
            1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示时图形失真大,(可通过安装字体平滑软件来解决); 4) 
            在低颜色位数的设备上(如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。 <BR><BR>---- 三、BMP位图缩放显示 
            <BR><BR>---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形进行淡化(Dithering 
            )处理。淡化处理是一种图形算法,可以用来在一个支持比图像所用颜色要少的设备上显示彩色图像。BMP位图显示方法如下: 
            <BR><BR>---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中 <BR><BR>---- 2. 
            申请内存空间用于存放位图文件 <BR><BR>---- GlobalAlloc(GHND,FileLength); 
            <BR><BR>---- 3. 位图文件读入所申请内存空间中 <BR><BR>---- LoadFileToMemory( 
            mpBitsSrc,mFileName); <BR><BR>---- 4. 
            在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图 <BR><BR>---- 5. 
            关闭视频函数DrawDibClose(),一般放在在析构函数中 <BR><BR>---- 以上方法的优点是: 1)显示速度快; 2) 
            内存占用少; 3) 缩放显示时图形失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 
            通过直接处理位图数据,可以制作简单动画。 <BR><BR>---- 四、CViewBimap类编程要点 <BR><BR>---- 1. 
            在CViewBimap类中添加视频函数等成员 <BR><BR>HDRAWDIB m_hDrawDib; // 
            视频函数<BR>HANDLEmhBitsSrc; // 位图文件句柄(内存)<BR>LPSTR mpBitsSrc; // 
            位图文件地址(内存)<BR>BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头<BR><BR>---- 
            2. 在CViewBimap类构造函数中添加打开视频函数 <BR><BR>---- m_hDrawDib= DrawDibOpen(); 
            <BR><BR>---- 3. 在CViewBimap类析构函数中添加关闭视频函数 <BR><BR>if( m_hDrawDib != 
            NULL)<BR>{<BR>DrawDibClose( m_hDrawDib);<BR>m_hDrawDib = 
            NULL;<BR>}<BR>---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() 
            <BR>voidCViewBitmap::OnPaint()<BR>{<BR>CPaintDC dc(this); // device 
            context for painting<BR>GraphicDraw( 
            );<BR>}<BR><BR>voidCViewBitmap::GraphicDraw( void 
            )<BR>{<BR>CClientDC dc(this); // device context for 
            painting<BR>BITMAPFILEHEADER *pBitmapFileHeader;<BR>ULONG bfoffBits= 
            0;<BR>CPoint Wid;<BR><BR>// 图形文件名有效 (=0 BMP)<BR>if( mBitmapFileType 
            &lt; ID_BITMAP_BMP ) return;<BR><BR>// 图形文件名有效 (=0 BMP)<BR>// 
            准备显示真彩位图<BR>pBitmapFileHeader= (BITMAPFILEHEADER *) 
            mpBitsSrc;<BR>bfoffBits= pBitmapFileHeader-&gt;bfOffBits;<BR><BR>// 
            使用普通函数显示位图<BR><BR>if( m_hDrawDib == NULL || mDispMethod == 
            0)<BR>{<BR>HBITMAP 
            hBitmap=::CreateDIBitmap(dc.m_hDC,<BR>mpBitmapInfo, CBM_INIT, 
            mpBitsSrc+bfoffBits,<BR>(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS); 
            <BR>// 建立位图<BR>HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 
            建立内存<BR>HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 
            选择对象<BR>// 成员CRect mDispR用于指示图形显示区域的大小.<BR>// 成员CPoint 
            mPos用于指示图形显示起始位置坐标.<BR>if( mPos.x &gt; (mpBitmapInfo- &gt;biWidth - 
            mDispR.Width() ))<BR>mPos.x= mpBitmapInfo-&gt;biWidth - 
            mDispR.Width() ;<BR>if( mPos.y &gt; (mpBitmapInfo- &gt;biHeight- 
            mDispR.Height()))<BR>mPos.y= mpBitmapInfo- &gt;biHeight- 
            mDispR.Height();<BR>if( mPos.x &lt; 0 ) mPos.x= 0;<BR>if( mPos.y 
            &lt; 0 ) mPos.y= 0;<BR><BR>if( mFullViewTog == 0)<BR>{<BR>// 
            显示真彩位图<BR>::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(), 
            <BR>hMemDC,mPos.x,mPos.y, SRCCOPY);<BR>} else 
            {<BR>::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), 
            mDispR.Height(),<BR>hMemDC,0,0, mpBitmapInfo- &gt;biWidth, 
            mpBitmapInfo- <BR>&gt;biHeight, SRCCOPY);<BR>}<BR>// 
            结束显示真彩位图<BR>::DeleteObject(SelectObject(hMemDC,hBitmapOld)); <BR>// 
            删 除 位 图<BR>} else {<BR><BR>// 使用视频函数显示位图<BR><BR>if( mPos.x &gt; 
            (mpBitmapInfo- &gt;biWidth - mDispR.Width() ))<BR>mPos.x= 
            mpBitmapInfo- &gt;biWidth - mDispR.Width() ;<BR>if( mPos.y &gt; 
            (mpBitmapInfo- &gt;biHeight- mDispR.Height()))<BR>mPos.y= 
            mpBitmapInfo- &gt;biHeight- mDispR.Height();<BR>if( mPos.x &lt; 0 ) 
            mPos.x= 0;<BR>if( mPos.y &lt; 0 ) mPos.y= 0;<BR><BR>// 
            显示真彩位图<BR>DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), 
            TRUE);<BR><BR>if( mFullViewTog == 0)<BR>{<BR>Wid.x= 
            mDispR.Width();<BR>Wid.y= mDispR.Height();<BR>// 1:1 显示时, 
            不能大于图形大小<BR>if( Wid.x &gt; mpBitmapInfo- &gt;biWidth ) <BR>Wid.x = 
            mpBitmapInfo- &gt;biWidth;<BR>if( Wid.y &gt; mpBitmapInfo- 
            &gt;biHeight) <BR>Wid.y = mpBitmapInfo- 
            &gt;biHeight;<BR><BR>DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()<BR>, 
            0, 0, Wid.x, Wid.y,<BR>mpBitmapInfo, (LPVOID) 
            (mpBitsSrc+bfoffBits),<BR>mPos.x, mPos.y, Wid.x, Wid.y, 
            DDF_BACKGROUNDPAL);<BR>} else {<BR>DrawDibDraw( m_hDrawDib, 
            dc.GetSafeHdc(),<BR>0, 0, mDispR.Width(), 
            mDispR.Height(),<BR>mpBitmapInfo, (LPVOID) 
            (mpBitsSrc+bfoffBits),<BR>0, 0, mpBitmapInfo- &gt;biWidth, 
            mpBitmapInfo- 
            &gt;biHeight,<BR>DDF_BACKGROUNDPAL);<BR>}<BR>}<BR>return;<BR>}<BR><BR>---- 
            五、使用CViewBimap类显示BMP位图 <BR><BR>---- 1. 在Visual 
            C++5.0中新建一个名称为mymap工程文件,类型为MFC 
            AppWizard[exe]。在编译运行通过后,在WorkSpace(如被关闭,用Alt_0打开)点击ResourceView,点击Menu左侧的+符号展开Menu 
            条目,双击IDR_MAINFRAME条目,进入菜单资源编辑,在'“查看(V)”下拉式菜单(英文版为View下拉式菜单)的尾部添加“ViewBitmap”条目,其ID为ID_VIEW_BITMAP。 
            <BR><BR>---- 2. 在Visual C++5.0中点击下拉式菜单Project- &gt;Add To project- 
            &gt;Files...,将Bitmap0.h 和Bitmap0.cpp添加到工程文件中。 <BR><BR>---- 3. 
            在Visual C++5.0中按Ctrl_W进入MFC ClassWizard,选择类名称为CMainFrame,ObjectIDs: 
            ID_VIEW_BITMAP,Messages选择Command,然后点击Add 
            Fucction按钮,然后输入函数名为OnViewBima p。在添加OnViewBimap后,在Member functions: 
            中点击OnViewBimap条目,点击Edit Code按钮编辑程序代码。代码如下: <BR><BR>void 
            CMainFrame::OnViewBitmap()<BR>{<BR>// TODO: Add your command handler 
            code here<BR>CViewBitmap *pViewBitmap= NULL;<BR><BR>pViewBitmap= new 
            CViewBitmap( "BITMAP.BMP", this);<BR>pViewBitmap- &gt;ShowWindow( 
            TRUE);<BR>}<BR><BR>---- 并在该程序的头部添加#include "bitmap0.h",然后编译运行。 
            <BR><BR>---- 4. 找一个大一点的真彩色的BMP位图,将它拷贝到BITMAP.BMP中。 <BR><BR>---- 5. 
            运行时,点击下拉式菜单“查看(V)- &gt;ViewBitmap”(英文版为View- &gt; 
            ViewBitmap)即可显示BITMAP.BMP位图。 <BR><BR>---- 六、CViewBimap类功能说明 
            <BR><BR>---- 1. 
            在客户区中带有水平和垂直滚动条。在位图大小大于显示客户区时,可以使用滚动条;在位图大小小于显示客户区或全屏显示时,滚动条无效。 
            <BR><BR>---- 2. 
            在客户区中底部带有状态条。状态条中的第一格为位图信息,第二格为位图显示方法,可以是使用普通函数或使用视频函数。在第二格区域内点击鼠标,可在两者之间接换。第三格为位图显示比例,可以是1;1显示或全屏显示。在第三格区域内点击鼠标,可在两者之间接换。在全屏显示时,如果位图比客户区小,则对位图放大; 
            如果位图比客户区大,则对位图缩小。 <BR><BR>---- 3. 
            支持文件拖放功能。可以从资源管理器中拖动一个位图文件到客户区,就可以显示该位图。 <BR><BR>---- 
            程序调试通过后,可以找一个较大的真彩色位图或调整客户区比位图小,在全屏显示方式下,比较使用普通函数与使用视频函数的差别。可以看出,位图放大时两者差别不大,但在位图缩小时,两者差别明显; 
            使用视频函数时位图失真小,显示速度快。 <BR><BR>---- 
            还可以从控制面板中将屏幕显示方式从真彩色显示模式切换到256色显示模式,再比较使用普通函数与使用视频函数显示同一个真彩色位图的差别。现在可以体会到使用视频函数的优越性了吧。 
            <BR><BR>---- 在全屏显示时,位图的xy方向比例不相同,如要保持相同比例,可在显示程序中加以适当调整即可,读者可自行完成。 
            <BR><BR>朱永辉 zyonghui@21cn.com 
        <BR><!--jcend--></DIV><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center bgColor=#006699 border=0 cellPadding=0 cellSpacing=0 
width=770>
  <TBODY>
  <TR bgColor=#006699>
    <TD align=middle bgColor=#006699 id=white><FONT 
    color=#ffffff>对该文的评论</FONT></TD>
    <TD align=middle>
      <SCRIPT src="CSDN_文档中心_BMP位图文件结构及VC操作.files/readnum.htm"></SCRIPT>
    </TD></TR></TBODY></TABLE><BR>
<DIV align=center>
<TABLE align=center bgColor=#cccccc border=0 cellPadding=2 cellSpacing=1 
width=770>
  <TBODY>
  <TR>
    <TH bgColor=#006699 id=white><FONT 
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<DIV align=center>
<TABLE border=0 width=770>
  <TBODY>
  <TR>
    <TD>你没有登陆,无法发表评论。 请先<A 
      href="http://www.csdn.net/member/login.asp?from=/Develop/read_article.asp?id=2103">登陆</A> 
      <A 
href="http://www.csdn.net/expert/zc.asp">我要注册</A><BR></TD></TR></TBODY></TABLE></DIV><BR>
<HR noShade SIZE=1 width=770>

<TABLE border=0 cellPadding=0 cellSpacing=0 width=500>
  <TBODY>
  <TR align=middle>
    <TD height=10 vAlign=bottom><A 
      href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A 
      href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A 
      href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A 
      href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A 
      href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A 
      href="http://www.csdn.net/english">English</A> </TD>
    <TD align=middle rowSpan=3><A 
      href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG 
      border=0 height=48 src="CSDN_文档中心_BMP位图文件结构及VC操作.files/biaoshi.gif" 
      width=40></A></TD></TR>
  <TR align=middle>
    <TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
  <TR align=middle>
    <TD vAlign=top><FONT face=Verdana>Copyright &copy; CSDN.net, Inc. All rights 
      reserved</FONT></TD></TR>
  <TR>
    <TD height=15></TD>
    <TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--内容结束//--><!--结束//--></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -