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;
}