#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