Bitmap对象保存到bmp文件中

      连续两三天没吃好,没睡好,就因为老师让把图片输出。可真苦了我啊,那做过这东西。百度,谷歌我是看了N百页,有多种多这样的方法,不过有的不符合我要求,有的压根就运行不了。比如上一篇日志所记录的方法,那是抓屏,然后输出到文件,非我所要啊。我要的是把已经存在的Bitmap对象输出到文件。

      在看了N边bmp相关的文章之后,终于决定慢慢自己写(不能总靠别人吃饭啊)。文件头、信息头部分完全可以写出,到数据部分,遇到不少困难,试了很多方法都以失败告终。最终利用网上一大虾的方法写出来了(百度一百能发现这位大侠的文章,不好意思我给忘了网址了,还是谢过!!)

void CShowImageView::OnTest3()
{
 CMainFrame* mainframe=(CMainFrame*)(AfxGetApp()->GetMainWnd()   );
 COilSpillOpticalDectDoc* pDoc=(COilSpillOpticalDectDoc*)GetDocument();
 
 CFile file;
 CFileException e;

 CFileDialog dlg(FALSE,"*.bmp",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
  "record file(*.bmp)|*.bmp|All Files(*.*)|*.*||");
 if(dlg.DoModal()!=IDOK)
  return;
 CString pathname=dlg.GetPathName();
// CString pathname.Format("%s/.bmp",pathname);
 if(!file.Open(pathname,CFile::modeCreate|CFile::modeReadWrite,&e))
 {
  AfxMessageBox("文件打开失败!错误码:%u\n",e.m_cause);
  return; 
 }

/* LPTSTR szFile=pathname.GetBuffer(pathname.GetLength()+1);
 pathname.ReleaseBuffer();
 CFile file;
 if(!file.Open(szFile,CFile::modeWrite|CFile::modeCreate))
  return ;
*/
//=pDoc->mem_bmp;
// if(view_bmp!=NULL) delete view_bmp;
 view_bmp=pDoc->mem_bmp;
 if(pDoc->ExReport==FALSE)//画布进行旋转
 {
  view_bmp->RotateFlip(RotateNoneFlipY);
  pDoc->ExReport=TRUE;
 }
 BITMAP bitmap;
 HBITMAP hbitmap;

 view_bmp->GetHBITMAP(Color(),&hbitmap);
 GetObject(hbitmap,   sizeof(bitmap),   (LPSTR)&bitmap);
// CBitmap* pbm = CBitmap::FromHandle(hbitmap);
// pbm->GetBitmap(&bitmap);

 LPBITMAPINFOHEADER lpbi;
 HANDLE fdib;
 BITMAPFILEHEADER bmfh;
 BITMAPINFOHEADER bi;
 bmfh.bfType=0x4d42;
 bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
 bmfh.bfSize=bmfh.bfOffBits+bitmap.bmWidth*bitmap.bmHeight*4;
 bmfh.bfReserved1=0;
 bmfh.bfReserved2=0;
 //DWORD dwSize=(pDoc->nBufferSizeX*8+31 )/32 * 4 *pDoc->nBufferSizeY;
 //int viewx=mainframe->viewX;
 //LONG bitmapx=bitmap.bmWidth;
 //biSizeImage=(biWidth*biBitCount+31)/32*4*biHeight
   bi.biSize =   sizeof(BITMAPINFOHEADER);  
   bi.biWidth =   bitmap.bmWidth;  
   bi.biHeight =   bitmap.bmHeight;  
   bi.biPlanes =   1;  
   bi.biBitCount =   32;  
   bi.biCompression =   BI_RGB;  
   bi.biSizeImage =bi.biWidth*4*bi.biHeight ;  
   bi.biXPelsPerMeter =   0;  
   bi.biYPelsPerMeter =   0;  
   bi.biClrImportant =   0;  
   bi.biClrUsed =   0; 

 
//计算位图的大小,并分配相应的内存空间,注意的是没有分配BITMAPFILEHEADER。
       DWORD dwbmdibitsize=((bitmap.bmWidth*32+31)/8)*bitmap.bmHeight;
       fdib=GlobalAlloc(GHND,dwbmdibitsize+sizeof(BITMAPINFOHEADER));
       lpbi=(LPBITMAPINFOHEADER)::GlobalLock(fdib);
       *lpbi=bi;//将bi中的数据写入分配的内存中。
       HDC hdc=::GetDC(NULL);
       GetDIBits(hdc,hbitmap,0,(UINT)bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER),(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
  

 
 file.Write(&bmfh,sizeof(BITMAPFILEHEADER));

 DWORD dwdibsize=sizeof(BITMAPINFOHEADER)+dwbmdibitsize;

 

 file.Write((LPSTR)lpbi,dwdibsize);
 ::GlobalUnlock(fdib);
    ::GlobalFree(fdib);
 file.Close();

 GetImgInfoView()->CreateReport(pathname);//,file);
 pDoc->dibfill=0;
 zoom=0;
}

posted @ 2009-05-09 13:48  gisbingxin  阅读(3363)  评论(0编辑  收藏  举报