//GDI+为图片的加载、存储,屏蔽了内部编解码、压缩解压缩等的具体细节,给程序员带来了极大的方便 //目前版本的GDI+支持bmp jpeg gif tiff png等几种格式 //下面的程序基本思路是先将目标DC上的内容存到内存BITMAP //再使用GDI+Bitmap::FromHBITMAP加载内存位图,并保存成文件 //此版本在Win32和MFC环境下测试通过 // //使用GDI+ 保存HDC为位图文件 #include <rpc.h> #include <rpcndr.h> #include <unknwn.h> #include <gdiplus.h> using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib") struct _GdiplusToken { Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; _GdiplusToken() { if(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != Ok) { MessageBox(NULL, _T("GdiplusStartup failed"), _T("Error"), MB_OK); } } ~_GdiplusToken() { Gdiplus::GdiplusShutdown(gdiplusToken); } }GdiplusToken; int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; Gdiplus::GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure Gdiplus::GetImageEncoders(num, size, pImageCodecInfo); for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure } BOOL SaveHDCToFile(HDC hDC, LPRECT lpRect) { BOOL bRet = FALSE; int nWidth = lpRect->right - lpRect->left; int nHeight = lpRect->bottom - lpRect->top; //将目标区域贴图到内存BITMAP HDC memDC = CreateCompatibleDC(hDC); HBITMAP hBmp = CreateCompatibleBitmap(hDC, nWidth, nHeight); SelectObject(memDC, hBmp); BitBlt(memDC, lpRect->left, lpRect->top, nWidth, nHeight, hDC, 0, 0, SRCCOPY); //保存成文件 { //L"image/bmp" L"image/jpeg" L"image/gif" L"image/tiff" L"image/png" CLSID pngClsid; GetEncoderClsid(L"image/bmp", &pngClsid);//此处以BMP为例,其它格式选择对应的类型,如JPG用L"image/jpeg" Gdiplus::Bitmap *pbmSrc = Gdiplus::Bitmap::FromHBITMAP(hBmp, NULL); if( pbmSrc->Save(L"C:\\test.bmp", &pngClsid) == Ok) { bRet = TRUE; } delete pbmSrc; } //清理工作 SelectObject(memDC, (HBITMAP)NULL); DeleteDC(memDC); DeleteObject(hBmp); return bRet; } [cpp] view plaincopy //Win32下的测试用例 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... TextOut(hdc, 0, 0, _T("ABCD"), 4); EndPaint(hWnd, &ps); break; case WM_KEYDOWN: { HDC hDC = GetDC(hWnd); RECT rcRect; GetClientRect(hWnd, &rcRect); SaveHDCToFile(hDC, &rcRect); ReleaseDC(hWnd, hDC); break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }