我需要写一些生成图片显示图片的MFC代码。比较简单,但在网上没有找到完整的例子。
我整理了一些代码,现实了此功能。共享之。
1.在内存DC上画图然后保存成BMP文件
#pragma once #include <Windows.h> class ForceCanvas { public: ForceCanvas(int canvasWithd, int canvasHeight); ~ForceCanvas(); void DrawLine(int x1, int y1, int x2, int y2, COLORREF penColor, int penWidth); void SetBackgroundColor(COLORREF backgroundColor); bool SaveBMP(const char * fileName); protected: HDC memDc; HDC dc; HBITMAP hBitmap; HGDIOBJ hOldBm; int myCanvasWithd; int myCanvasHeight; }; ForceCanvas::ForceCanvas(int canvasWithd, int canvasHeight) :myCanvasWithd(canvasWithd), myCanvasHeight(canvasHeight) { memDc = ::CreateCompatibleDC(NULL); //创建一个兼容dc dc = ::GetDC(NULL); hBitmap = ::CreateCompatibleBitmap(dc, canvasWithd, canvasHeight); hOldBm = ::SelectObject(memDc, hBitmap); //选入设备 保存老的设备以便恢复 } ForceCanvas::~ForceCanvas() { DeleteObject(hBitmap); DeleteDC(memDc); ::ReleaseDC(NULL, dc); } void ForceCanvas::DrawLine(int x1, int y1, int x2, int y2, COLORREF penColor, int penWidth) { HGDIOBJ hPen = ::CreatePen(PS_SOLID, penWidth, penColor); ::SelectObject(memDc, hPen); ::MoveToEx(memDc, x1, y1, NULL); ::LineTo(memDc, x2, y2); ::DeleteObject(hPen); //MoveToEx最后一个参数的意思 //Pointer to a POINT structure that receives the previous current position. //If this parameter is a NULL pointer, the previous position is not returned. } bool ForceCanvas::SaveBMP(const char * fileName) { WORD wBitCount;//位图中每象素所占字节数 DWORD dwPaletteSize=0;//定义调色板大小 DWORD dwBmBitsSize=0;//位图中像素字节大小 DWORD dwDIBSize=0;//位图文件大小 DWORD dwWritten=0;//写入文件字节数 BITMAP Bitmap;//位图属性结构 BITMAPFILEHEADER bmfHdr;//位图文件头结构 BITMAPINFOHEADER bi;//位图信息头结构 LPBITMAPINFOHEADER lpbi;//指向位图信息头结构 //定义文件,分配内存句柄,调色板句柄 HANDLE fh=NULL; HANDLE hDib=NULL; HANDLE hPal=NULL; HANDLE hOldPal=NULL; wBitCount = 24; 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.biClrImportant = 0; bi.biClrUsed = 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); HDC hDC; if (hPal) { hDC = ::GetDC(NULL); hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE); RealizePalette(hDC); } else { return false; } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); //恢复调色板 if (hOldPal) { ::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE); RealizePalette(hDC); ::ReleaseDC(NULL, hDC); } //创建位图文件 fh = CreateFile(fileName, 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; } void ForceCanvas::SetBackgroundColor(COLORREF backgroundColor) { HBRUSH brush = CreateSolidBrush(backgroundColor); RECT rect={0, 0, myCanvasWithd, myCanvasHeight}; HGDIOBJ oldBrush = SelectObject(memDc, brush); FillRect(memDc, &rect, brush); SelectObject(memDc, oldBrush); DeleteObject(brush); } void main() { ForceCanvas canvas(500, 500); canvas.SetBackgroundColor(RGB(255,255,255)); canvas.DrawLine(100,100,500,100, RGB(0,255,0),3); canvas.SaveBMP("c:\\t.bmp"); }
2.读入Bmp文件,显示在对话框的静态控件上
void DrawPictureFromBmpFile(CDialog * dlg, int pictureCtrlID, const char * fileName) { CStatic *pWnd = (CStatic *)dlg->GetDlgItem(pictureCtrlID); if (pWnd == 0) return; HANDLE filehandle=::LoadImage(NULL, fileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE); if(filehandle!=NULL) { CBitmap bmp; if(bmp.Attach(filehandle)) { CDC * pDC = pWnd->GetDC(); BITMAP bmpInfo; bmp.GetBitmap(&bmpInfo); CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); dcMemory.SelectObject(&bmp); pDC->SetStretchBltMode(HALFTONE); //获取Static控件的大小范围 CRect rect; pWnd->GetClientRect(&rect); pDC->StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcMemory,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY); bmp.Detach(); } } }