#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
}
void SaveWndToJpeg(HWND hSrcWnd, //源窗口
BOOL bXMirror, //X轴镜像?
BOOL bYMirror, //Y轴镜像?
LPCWSTR wcsFileName) //目标文件名
{
HDC hSrcDC = GetDC(hSrcWnd);
int nWdith = GetDeviceCaps(hSrcDC, HORZRES);
int nHeigth = GetDeviceCaps(hSrcDC, VERTRES);
HDC hMemDC = CreateCompatibleDC(hSrcDC);
HBITMAP hMemBitmap = CreateCompatibleBitmap(hSrcDC, nWdith, nHeigth);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hMemBitmap);
//映射模式
int iMapMode = SetMapMode(hMemDC, MM_ANISOTROPIC);
SIZE szViewportExt, szWindowExt;
SetViewportExtEx(hMemDC, bXMirror? -1:1, //-1:X轴镜像 1X轴不镜像
bYMirror? -1:1, //-1Y轴镜像 1Y轴不镜像
&szViewportExt);
SetWindowExtEx(hMemDC, 1, 1, &szWindowExt);
//坐标原点
POINT ptOrg;
SetViewportOrgEx(hMemDC, bXMirror? nWdith:0, bYMirror? nHeigth:0, //设置坐标原点
&ptOrg);
//绘制代码
BitBlt(hMemDC, 0, 0, nWdith, nHeigth, hSrcDC, 0, 0, SRCCOPY);
//恢复映射模式、坐标轴方向及坐标原点
SetMapMode(hMemDC, iMapMode);
SetViewportExtEx(hMemDC, szViewportExt.cx, szViewportExt.cy, NULL);
SetWindowExtEx(hMemDC, szWindowExt.cx, szWindowExt.cy, NULL);
SetViewportOrgEx(hMemDC, ptOrg.x, ptOrg.y, NULL);
//使用GDI+保存成jpeg
Gdiplus::Bitmap image(hMemBitmap, NULL);
CLSID pngClsid;
GetEncoderClsid(L"image/jpeg", &pngClsid);
image.Save(wcsFileName, &pngClsid, NULL);
//结束恢复
SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
DeleteObject(hMemBitmap);
ReleaseDC(hSrcWnd, hSrcDC);
}
//WIN32下的测试代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
default:
return DefWindowProc(hWnd, message, wParam, lParam);
case IDM_X0_Y0:
SaveWndToJpeg(GetDesktopWindow(), FALSE, FALSE, L"C:\\x0y0.jpg");
break;
case IDM_X0_Y1:
SaveWndToJpeg(GetDesktopWindow(), FALSE, TRUE, L"C:\\x0y1.jpg");
break;
case IDM_X1_Y0:
SaveWndToJpeg(GetDesktopWindow(), TRUE, FALSE, L"C:\\x1y0.jpg");
break;
case IDM_X1_Y1:
SaveWndToJpeg(GetDesktopWindow(), TRUE, TRUE, L"C:\\x1y1.jpg");
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
测试输出图片(0不镜像 1镜像) X0Y0 X1Y0 X0Y1 X1Y1