CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  图形处理/算法

关于把内存位图直接保存为位图文件

楼主Goldbach(hufuping)2006-03-13 13:01:52 在 VC/MFC / 图形处理/算法 提问

我想在内存中画位图,然后直接保存(即不在屏幕上显示)为位图文件。  
  前提是在对话框中实现:  
  点击一个按钮,程序就会产生一个位图文件。  
  这个该怎么做?  
   
  各位大虾帮帮忙,先谢了! 问题点数:100、回复次数:8Top

1 楼Mackz(在相互)回复于 2006-03-13 13:17:15 得分 60

//********************************************************************************  
  //*   名称:SaveBitmapToFile  
  //*   修改:徐景周(jingzhou_xu@163.net)  
  //*   功能:保存为位图文件  
  //********************************************************************************  
  BOOL   CScreenSnapDlg::SaveBitmapToFile(HBITMAP   hBitmap   ,   CString   lpFileName)    
  {                    
          HDC                                 hDC;                                                         //设备描述表      
          int                                 iBits;                                                         //当前显示分辨率下每个像素所占字节数  
          WORD                         wBitCount;                                                 //位图中每个像素所占字节数  
          DWORD                       dwPaletteSize=0,                                 //定义调色板大小,   位图中像素字节大小   ,位图文件大小   ,   写入文件字节数  
                                          dwBmBitsSize,  
                                          dwDIBSize,   dwWritten;  
          BITMAP                     Bitmap;                  
          BITMAPFILEHEADER       bmfHdr;                                                 //位图属性结构          
          BITMAPINFOHEADER       bi;                                                         //位图文件头结构                
          LPBITMAPINFOHEADER   lpbi;                                                 //位图信息头结构            
          HANDLE                     fh,   hDib,   hPal,hOldPal=NULL;         //指向位图信息头结构,定义文件,分配内存句柄,调色板句柄  
       
        //计算位图文件每个像素所占字节数  
        hDC   =   CreateDC("DISPLAY",NULL,NULL,NULL);  
        iBits   =   GetDeviceCaps(hDC,   BITSPIXEL)   *    
        GetDeviceCaps(hDC,   PLANES);  
        DeleteDC(hDC);  
        if   (iBits   <=   1)  
              wBitCount   =   1;  
        else   if   (iBits   <=   4)  
              wBitCount   =   4;  
        else   if   (iBits   <=   8)  
              wBitCount   =   8;  
        else   if   (iBits   <=   24)  
              wBitCount   =   24;  
        //计算调色板大小  
        if   (wBitCount   <=   8)  
              dwPaletteSize   =   (1   <<   wBitCount)   *sizeof(RGBQUAD);  
         
        //设置位图信息头结构  
        GetObject(hBitmap,   sizeof(BITMAP),   (LPSTR)&Bitmap);  
        bi.biSize                         =   sizeof(BITMAPINFOHEADER);  
        bi.biWidth                       =   Bitmap.bmWidth;  
        bi.biHeight                     =   Bitmap.bmHeight;  
        bi.biPlanes                     =   1;  
        bi.biBitCount                   =   wBitCount;  
        bi.biCompression             =   BI_RGB;  
        bi.biSizeImage                 =   0;  
        bi.biXPelsPerMeter           =   0;  
        bi.biYPelsPerMeter           =   0;  
        bi.biClrUsed                   =   0;  
        bi.biClrImportant             =   0;  
   
        dwBmBitsSize   =   ((Bitmap.bmWidth   *  
          wBitCount+31)/32)*   4  
            *Bitmap.bmHeight   ;  
   
        //为位图内容分配内存  
        hDib     =   GlobalAlloc(GHND,dwBmBitsSize+  
          dwPaletteSize+sizeof(BITMAPINFOHEADER));  
        lpbi   =   (LPBITMAPINFOHEADER)GlobalLock(hDib);  
        *lpbi   =   bi;  
   
        //   处理调色板        
        hPal   =   GetStockObject(DEFAULT_PALETTE);  
        if   (hPal)  
        {  
                hDC     =   ::GetDC(NULL);  
                hOldPal   =   SelectPalette(hDC,   (HPALETTE)hPal,   FALSE);  
                RealizePalette(hDC);  
        }  
   
        //   获取该调色板下新的像素值  
        GetDIBits(hDC,   hBitmap,   0,   (UINT)   Bitmap.bmHeight,  
            (LPSTR)lpbi   +   sizeof(BITMAPINFOHEADER)+dwPaletteSize,  
            (LPBITMAPINFO)lpbi,   DIB_RGB_COLORS);  
   
        //恢复调色板        
        if   (hOldPal)  
        {  
              SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);  
              RealizePalette(hDC);  
              ::ReleaseDC(NULL,   hDC);  
        }  
   
        //创建位图文件          
          fh   =   CreateFile(lpFileName,   GENERIC_WRITE,    
                    0,   NULL,   CREATE_ALWAYS,  
                    FILE_ATTRIBUTE_NORMAL   |   FILE_FLAG_SEQUENTIAL_SCAN,   NULL);  
   
        if   (fh   ==   INVALID_HANDLE_VALUE)  
              return   FALSE;  
   
        //   设置位图文件头  
        bmfHdr.bfType   =   0x4D42;     //   "BM"  
        dwDIBSize         =   sizeof(BITMAPFILEHEADER)   +   sizeof(BITMAPINFOHEADER)   +   dwPaletteSize   +   dwBmBitsSize;      
        bmfHdr.bfSize   =   dwDIBSize;  
        bmfHdr.bfReserved1   =   0;  
        bmfHdr.bfReserved2   =   0;  
        bmfHdr.bfOffBits   =   (DWORD)sizeof(BITMAPFILEHEADER)    
              +   (DWORD)sizeof(BITMAPINFOHEADER)  
            +   dwPaletteSize;  
   
        //   写入位图文件头  
        WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof  
          (BITMAPFILEHEADER),   &dwWritten,   NULL);  
        //   写入位图文件其余内容  
        WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,    
        &dwWritten,   NULL);  
   
        //消除内存分配      
        GlobalUnlock(hDib);  
        GlobalFree(hDib);  
        CloseHandle(fh);  
   
        return   TRUE;  
  }Top

2 楼wenkui(黒眼看红尘)回复于 2006-03-15 11:05:29 得分 10

这个程序应该写的比较早了   没考虑32位的情形    
  而现在大多数显卡的显示色彩是32位的   应该在if里加上32位Top

3 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2006-03-15 12:28:13 得分 10

这里面关键是提取出数据流,bmp文件的结构非常简单  
   
  还有16位的(r5g5b5和r5g6b5两种)情况呢,  
  http://www.hf110.com/Article/jswz/bcjs/ozh/200504/888.html  
   
   
  Top

4 楼Goldbach(hufuping)回复于 2006-03-15 20:03:17 得分 0

谢谢各位的支持  
  不过小弟   对画图一窍不通,  
  Mackz(在相互)   的程序能不能精简啊,小弟看不太懂  
   
  另外,我希望保存的位图是16色的。Top

5 楼Goldbach(hufuping)回复于 2006-03-15 20:31:18 得分 0

我还是把代码贴出来,这样大家对我的需求更清晰:  
  按缺省值建立一个基于MFC的对话框程序,添加了一个按钮(IDC_BUTTON1),对应的相应函数如下  
   
  void   CHhhhDlg::OnButton1()    
  {  
            //   TODO:   Add   your   control   notification   handler   code   here  
            CClientDC   clientDC(this);  
            CDC   memDC;  
            memDC.CreateCompatibleDC(&clientDC);  
   
            CRect   rcClient;  
            GetClientRect(&rcClient);  
            CBitmap   membitmap;  
            membitmap.CreateCompatibleBitmap(&clientDC,   rcClient.Width(),    
                    rcClient.Height());  
            memDC.SelectObject(&membitmap);  
   
            for   (int   x   =   0;   x   <   rcClient.right;   x   ++)  
            {  
  for   (int   y   =   0;   y   <   rcClient.bottom;   y   ++)  
  {  
            memDC.SetPixel(x,   y,   x   <   y   ?   RGB(255,   255,   0)   :   RGB(255,   0,   0));  
  }  
            }  
   
            clientDC.BitBlt(0,   0,   rcClient.Width(),   rcClient.Height(),    
  &memDC,   0,   0,   SRCCOPY);  
            //   现在我就想把最后一句换掉,不把位图复制到屏幕上,而是把内存中的位图直接保  
            //   存到BMP文件中,颜色设置为16色,该怎么写?  
   
   
  }  
  Top

6 楼xuzheng318(忧郁王子)回复于 2006-03-15 20:49:08 得分 10

http://dev.poptool.net/vc++/2005-09-01/0509010220.htmlTop

7 楼yuanss71(yuanss71)回复于 2006-03-26 08:57:10 得分 10

http://www.vccode.net/forum_view.asp?forum_id=11&view_id=432Top

8 楼Mackz(在相互)回复于 2006-03-27 13:52:07 得分 0

再精简就没有了,不懂得可以学习么。Top

相关问题

  • 如何把内存位图保存为文件?
  • 问题:如何保存在内存设备绘制的图到文件里面?
  • 请教如何将内存中的图像保存为BMP格式文件
  • 如何将内存DC中的图象在内存释放前保存成bmp文件!
  • 80分求教如何将内存中的图像数据保存为.bmp文件
  • 如何在内存DC上绘图,然后把内存DC上的图以位图的形式保存为文件?
  • 图象文件的保存
  • 图片保存到内存的问题
  • 请问如何修改内存中和文件中保存的cookies?
  • 请问从内存中把文件保存到硬盘上用那个函数

关键词

  • 文件
  • 内存
  • 像素
  • 结构
  • null
  • 图
  • 保存
  • ibits
  • hdc
  • 大小

得分解答快速导航

  • 帖主:Goldbach
  • Mackz
  • wenkui
  • happy__888
  • xuzheng318
  • yuanss71

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo