使用GDI+ 将HDC保存到本地图片文件
/*
*GDI+支持bmp jpeg gif tiff png等几种格式
*下面的程序基本思路是先将目标DC上的内容存到内存BITMAP
*再使用GDI+Bitmap::FromHBITMAP加载内存位图,并保存成文件
*/
#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"D:\\test.bmp", &pngClsid) == Ok)
{
bRet = TRUE;
}
delete pbmSrc;
}
//清理工作
SelectObject(memDC, (HBITMAP)NULL);
DeleteDC(memDC);
DeleteObject(hBmp);
return bRet;
}
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;
}
版权声明:本文为本站原创文章,转载请注明出处,非常感谢,如版权漏申明或您觉得任何有异议的地方欢迎与本站取得联系。