使用GDI+ 保存HDC为位图文件

//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;  

}  

 

你可能感兴趣的:(文件)