在用vc做程序时候,经常需要把输出的文本和图形保存到位图文件,当然可以有现成的控件来实现,但总不能如自己所愿,还是自己动手写吧!如下图:
一、实现方法
要把文本和图形保存到位图文件,只要对掌握位图结构有一定的了解,一切都ok呢。先必须要创建内存设备环境,然后内存设备环境创建的DIB区域,别忘了还要创建个CBitmap对象,CBitmap对象必须和DIB区域关联起来,把CBitmap对象选择到当前设备环境,然后在当前设备环境输出文本和图形就可以了。
二、具体实现代码如下
void CTestSaveBmpView::SaveAsBmp(CString filename) { //定义图形大小 int iWidth = 800; int iHeight = 600; int iPixel = 16; //图形格式参数 LPBITMAPINFO lpbmih = new BITMAPINFO; lpbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbmih->bmiHeader.biWidth = iWidth; lpbmih->bmiHeader.biHeight = iHeight; lpbmih->bmiHeader.biPlanes = 1; lpbmih->bmiHeader.biBitCount = iPixel; lpbmih->bmiHeader.biCompression = BI_RGB; lpbmih->bmiHeader.biSizeImage = 0; lpbmih->bmiHeader.biXPelsPerMeter = 0; lpbmih->bmiHeader.biYPelsPerMeter = 0; lpbmih->bmiHeader.biClrUsed = 0; lpbmih->bmiHeader.biClrImportant = 0; //创建位图数据 HDC hdc,hdcMem; HBITMAP hBitMap = NULL; CBitmap *pBitMap = NULL; CDC *pMemDC = NULL; BYTE *pBits; hdc = CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL); hdcMem = CreateCompatibleDC(hdc); hBitMap = CreateDIBSection(hdcMem,lpbmih,DIB_PAL_COLORS,(void **)&pBits,NULL,0); pBitMap = new CBitmap; pBitMap->Attach(hBitMap); pMemDC = new CDC; pMemDC->Attach(hdcMem); pMemDC->SelectObject(pBitMap); // CRect rc(0,0,iWidth,iHeight); pMemDC->SetBkMode(TRANSPARENT); //添加自绘图形 DrawCurve(pMemDC,rc); //保存到文件并创建位图结构 BITMAPFILEHEADER bmfh; ZeroMemory(&bmfh,sizeof(BITMAPFILEHEADER)); *((char *)&bmfh.bfType) = ''B''; *(((char *)&bmfh.bfType) + 1) = ''M''; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmfh.bfSize = bmfh.bfOffBits + (iWidth * iHeight) * iPixel / 8; TCHAR szBMPFileName[128]; int iBMPBytes = iWidth * iHeight * iPixel / 8; strcpy(szBMPFileName,filename); CFile file; if(file.Open(szBMPFileName,CFile::modeWrite | CFile::modeCreate)) { file.Write(&bmfh,sizeof(BITMAPFILEHEADER)); file.Write(&(lpbmih->bmiHeader),sizeof(BITMAPINFOHEADER)); file.Write(pBits,iBMPBytes); file.Close(); } pMemDC->DeleteDC(); delete pMemDC; pMemDC = NULL; delete pBitMap; pBitMap = NULL; delete lpbmih; lpbmih = NULL; } //输出文本和图形 void CTestSaveBmpView::DrawCurve(CDC *pDC, CRect rcClient) { //页面背景色 CBrush brushCtl; brushCtl.CreateSolidBrush(RGB(255,255,255)); pDC->Rectangle(rcClient); pDC->FillRect(rcClient,&brushCtl) ; brushCtl.DeleteObject(); CPen pen; pen.CreatePen(PS_SOLID, 1, RGB(255,0,0)); CPen *oldPen = pDC->SelectObject(&pen); double xMin = 10.00f, xMax = 100.00f; double yMin = 10.00f, yMax = 200.00f; double dbX1 = (xMax- xMin)/100 + xMin; double dbY1 = 600/dbX1 ; for (int i=1; i<100; i++) //曲线 { double dbX2 = (xMax- xMin)*i/100 + xMin; double dbY2 = 600/dbX2 ; pDC->MoveTo(int(rcClient.left+(dbX1 - xMin)*rcClient.Width()/(xMax- xMin)), int(rcClient.bottom-(dbY1- yMin)*rcClient.Height()/(yMax- yMin))); pDC->LineTo(int(rcClient.left+(dbX2 - xMin)*rcClient.Width()/(xMax- xMin)), int(rcClient.bottom-(dbY2- yMin)*rcClient.Height()/(yMax- yMin))); dbX1=dbX2; dbY1=dbY2; } pDC->SelectObject(oldPen); pen.DeleteObject(); oldPen = NULL; } //保存的实现 void CTestSaveBmpView::OnRButtonDown(UINT nFlags, CPoint point) { CFileDialog dlg(false,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "位图文件(*.bmp)|*.bmp|", NULL); if (dlg.DoModal()!= IDOK) return; CString filename = dlg.GetFileName() + ".bmp"; SaveAsBmp(filename); CView::OnRButtonDown(nFlags, point); }