GDI+ 保存指定的窗口为JPEG文件(X Y轴镜像功能可选)

 


#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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值