Windows 图片保存

来源:互联网 发布:淘宝我的评论在哪里 编辑:程序博客网 时间:2024/04/30 09:36

用GDI+的方式实现保存图片,

一、支持的图片格式

        enumSaveImageType_bmp       = 0x01,     ///>保存成BMP
        enumSaveImageType_jpeg      = 0x02,     ///>保存成JPG
        enumSaveImageType_gif       = 0x03,     ///>保存成单帧的GIF
        enumSaveImageType_tiff      = 0x04,     ///>保存成单帧的TIF
        enumSaveImageType_png       = 0x05      ///>保存成PNG


二、图片来源

        可以是以下来源之一:窗口句柄、设备上下文、位图句柄


三、实现代码

        该例子可以直接使用,公共调用接口包含详细的说明,主要的保存都由一个私有成员函数完成。具体代码如下:

头文件

////////////////////////////////////////////////////////////////////////////// @ File   : kgdiplusimagemgr.h// @ Data   : 2014-01-07 11:26:12// @ Remark : GDIPlus的Image辅助类////////////////////////////////////////////////////////////////////////////#ifndef __DEFINE___KGDIPLUSIMAGEMGR_H_#define __DEFINE___KGDIPLUSIMAGEMGR_H_#include <GdiPlus.h>///>图片类型#define IMAGE_TYPE_BMP          L"image/bmp"#define IMAGE_TYPE_JPEG         L"image/jpeg"#define IMAGE_TYPE_GIF          L"image/gif"#define IMAGE_TYPE_TIFF         L"image/tiff"#define IMAGE_TYPE_PNG          L"image/png"//////////////////////////////////////////////////////////////////////////class KGdiplusImageMgr{public:    enum _ENUMSAVEIMAGETYPE                     ///>保存图片类型    {        enumSaveImageType_bmp       = 0x01,     ///>保存成BMP        enumSaveImageType_jpeg      = 0x02,     ///>保存成JPG        enumSaveImageType_gif       = 0x03,     ///>保存成单帧的GIF        enumSaveImageType_tiff      = 0x04,     ///>保存成单帧的TIF        enumSaveImageType_png       = 0x05      ///>保存成PNG    };public:    KGdiplusImageMgr();    ~KGdiplusImageMgr();public:    /**    * @ brief   : 根据图片类型获取对应的CLSID,从系统可用编码器信息获得    * @ param   : [IN]  lpstrImageType 图片类型,宏定义IMAGE_TYPE_*    * @ param   : [OUT] pclsID 获取到的CLSID    * @ return  : TRUE 表示获取成功,否则获取失败    **/    BOOL GetImageCLSID(        /*_in_*/    LPCWSTR lpstrImageType,         /*_out_*/   CLSID* pclsID        );    /**    * @ brief   : 根据传递的窗口句柄或者设备上下文保存指定区域的内容到图片    * @ param   : [IN] hWnd 窗口句柄,一般传递用于保存图片的那个窗口    * @ param   : [IN] hDC 包含要保存内容的设备上下文,这个句柄外部是GetDC方式获得    *                  那么外部需要自己去释放。    * @ param   : [IN] hBitmap 已经要保存的位图句柄    * @ param   : [IN] lpstrPath 图片名,全路径或相对路径(相对于当前调用者)                       每个类型的图片需要带后缀名,内部不会做类型检查    * @ param   : [IN] lpRect 需要保存的区域大小,在使用HDC来保存图片的时候,                       如果lpRect为NULL,则自动获取桌面DC    * @ param   : [IN] nImgType 保存图片类型,目前支持5种类型    * @ return  : TRUE 表示保存成功    * @ comment : 将要保存的内容加载到内存DC,使用内存DC的HBITMAP去保存图片    **/    BOOL SaveImage(        /*_in_*/    HWND hWnd,         /*_in_*/    LPCWSTR lpstrPath,         /*_in_*/    LPRECT lpRect = NULL,         /*_in_*/    int nImgType = enumSaveImageType_png        );    BOOL SaveImage(        /*_in_*/    HDC hDC,         /*_in_*/    LPCWSTR lpstrPath,         /*_in_*/    LPRECT lpRect,         /*_in_*/    int nImgType = enumSaveImageType_png        );    BOOL SaveImage(        /*_in_*/    HBITMAP hBitmap,        /*_in_*/    LPCWSTR lpstrPath,        /*_in_*/    int nImgType = enumSaveImageType_png        );private:    HBITMAP _GetSaveImage(        HWND hWnd,         HDC hDC,          LPRECT lpRect,         int nImgType        );    BOOL _SaveImageAs(        HBITMAP hBitmap,         LPCWSTR lpstrPath,         int nImageType        );};#endif ///> __DEFINE___KGDIPLUSIMAGEMGR_H_//////////////////////////////////////////////////////////////////////////


实现

////////////////////////////////////////////////////////////////////////////// @ File   : kgdiplusimagemgr.cpp// @ Data   : 2014-01-07 11:57:21// @ Remark : GDIPlus的Image辅助类////////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include <Gdiplus.h>#include <Shlwapi.h>#include "kgdiplusimagemgr.h"//////////////////////////////////////////////////////////////////////////KGdiplusImageMgr::KGdiplusImageMgr(){}KGdiplusImageMgr::~KGdiplusImageMgr(){}BOOL KGdiplusImageMgr::GetImageCLSID(LPCWSTR lpstrImageType, CLSID* pclsID){    BOOL bRet = FALSE;    UINT uNumEncoders = 0;    UINT uCodeInfoSize = 0;    Gdiplus::ImageCodecInfo* pImageCodeInfo = NULL;        if (lpstrImageType == NULL || pclsID == NULL)    {        goto Exit0;    }        ///>获取系统支持的解码器信息数量    UINT uGdiplusRet = Gdiplus::GetImageEncodersSize(&uNumEncoders, &uCodeInfoSize);    if (uGdiplusRet != Gdiplus::Ok ||        uNumEncoders == 0 ||        uCodeInfoSize == 0)    {        goto Exit0;    }    pImageCodeInfo = (Gdiplus::ImageCodecInfo*)malloc(uCodeInfoSize);    if (pImageCodeInfo == NULL)    {        goto Exit0;    }    ///>获取系统支持的解码器的详细信息    uGdiplusRet = Gdiplus::GetImageEncoders(uNumEncoders, uCodeInfoSize, pImageCodeInfo);    if (uGdiplusRet != Gdiplus::Ok)    {        goto Exit0;    }    ///>查找指定类型的CLSID    for (UINT uIndex = 0; uIndex < uNumEncoders; ++uIndex)    {        if (pImageCodeInfo[uIndex].MimeType == NULL ||            StrCmp(lpstrImageType, pImageCodeInfo[uIndex].MimeType) != 0)        {            continue;        }        *pclsID = pImageCodeInfo[uIndex].Clsid;        bRet = TRUE;        break;    }    Exit0:    if (pImageCodeInfo != NULL)    {        free(pImageCodeInfo);        pImageCodeInfo = NULL;    }    return bRet;}BOOL KGdiplusImageMgr::SaveImage(HWND hWnd,                                  LPCWSTR lpstrPath,                                  LPRECT lpRect /* = NULL */,                                  int nImgType /* = enumSaveImageType_png */){    BOOL bRet = FALSE;    HBITMAP hBitmap = NULL;        if (hWnd == NULL || lpstrPath == NULL)    {        goto Exit0;    }    hBitmap = _GetSaveImage(hWnd, NULL, lpRect, nImgType);    if (hBitmap == NULL)    {        goto Exit0;    }    bRet = _SaveImageAs(hBitmap, lpstrPath, nImgType);    ::DeleteObject(hBitmap);    hBitmap = NULL;Exit0:    return bRet;}BOOL KGdiplusImageMgr::SaveImage(HDC hDC,                                  LPCWSTR lpstrPath,                                  LPRECT lpRect,                                  int nImgType /* = enumSaveImageType_png */){    BOOL bRet = FALSE;    HBITMAP hBitmap = NULL;    if (hDC == NULL || lpstrPath == NULL)    {        goto Exit0;    }    hBitmap = _GetSaveImage(NULL, hDC, lpRect, nImgType);    if (hBitmap == NULL)    {        goto Exit0;    }    bRet = _SaveImageAs(hBitmap, lpstrPath, nImgType);    ::DeleteObject(hBitmap);    hBitmap = NULL;Exit0:    return bRet; }BOOL KGdiplusImageMgr::SaveImage(HBITMAP hBitmap,                                  LPCWSTR lpstrPath,                                  int nImgType /* = enumSaveImageType_png */){    BOOL bRet = FALSE;        if (hBitmap == NULL || lpstrPath == NULL)    {        goto Exit0;    }    bRet = _SaveImageAs(hBitmap, lpstrPath, nImgType);Exit0:    return bRet;}HBITMAP KGdiplusImageMgr::_GetSaveImage(HWND hWnd,                                         HDC hDC,                                         LPRECT lpRect,                                         int nImgType){    HDC hMemDC = NULL;    RECT rcWnd = {0};    BOOL bManaged = FALSE;    HBITMAP hBitmap = NULL;    HBITMAP hOldmap = NULL;    if (hDC != NULL)    {        if (lpRect == NULL)        {            hDC = ::GetDC(NULL);            rcWnd.right  = ::GetSystemMetrics(SM_CXSCREEN);            rcWnd.bottom = ::GetSystemMetrics(SM_CYSCREEN);            bManaged = hDC != NULL ? TRUE : FALSE;        }        else        {            rcWnd = *lpRect;        }    }    else if (hWnd != NULL)    {        hDC = ::GetDC(hWnd);        if (lpRect == NULL)        {            ::GetClientRect(hWnd, &rcWnd);        }        else        {            rcWnd = *lpRect;        }        bManaged = hDC != NULL ? TRUE : FALSE;    }    UINT uWidth = abs(rcWnd.right - rcWnd.left);    UINT uHeight = abs(rcWnd.bottom - rcWnd.top);    if (uWidth == 0 || uHeight == 0 || hDC == NULL)    {        goto Exit0;    }    hMemDC = ::CreateCompatibleDC(hDC);    hBitmap = ::CreateCompatibleBitmap(hDC, uWidth, uHeight);    if (hMemDC == NULL || hBitmap == NULL)    {        goto Exit0;    }    hOldmap = (HBITMAP)::SelectObject(hMemDC, hBitmap);    ::BitBlt(hMemDC, 0, 0, uWidth, uHeight, hDC, 0, 0, SRCCOPY);    if (hMemDC != NULL && hOldmap != NULL)    {        ::SelectObject(hMemDC, hOldmap);        hOldmap = NULL;    }Exit0:    if (hMemDC != NULL)    {        ::DeleteDC(hMemDC);        hMemDC = NULL;    }    if (hDC != NULL && bManaged)    {        ::ReleaseDC(hWnd, hDC);        hDC = NULL;    }    return hBitmap;}BOOL KGdiplusImageMgr::_SaveImageAs(HBITMAP hBitmap,                                     LPCWSTR lpstrPath,                                     int nImageType){    BOOL bRet = FALSE;    CLSID clsID = {0};    Gdiplus::Status gdiRet;    Gdiplus::Bitmap* pImage = NULL;    pImage = new Gdiplus::Bitmap(hBitmap, NULL);    if (pImage == NULL)    {        goto Exit0;    }    switch (nImageType)    {       case enumSaveImageType_bmp:        if (GetImageCLSID(IMAGE_TYPE_BMP, &clsID) && clsID != GUID_NULL)        {            gdiRet = pImage->Save(lpstrPath, &clsID);        }        break;    case enumSaveImageType_jpeg:        if (GetImageCLSID(IMAGE_TYPE_JPEG, &clsID) && clsID != GUID_NULL)        {            UINT uQualty = 100;            Gdiplus::EncoderParameters encoderParams;            encoderParams.Count = 1;            encoderParams.Parameter[0].Guid = Gdiplus::EncoderQuality;            encoderParams.Parameter[0].NumberOfValues = 1;            encoderParams.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;            encoderParams.Parameter[0].Value = &uQualty;            gdiRet = pImage->Save(lpstrPath, &clsID, &encoderParams);        }        break;    case enumSaveImageType_gif:        if (GetImageCLSID(IMAGE_TYPE_GIF, &clsID) && clsID != GUID_NULL)        {            gdiRet = pImage->Save(lpstrPath, &clsID);        }        break;    case enumSaveImageType_tiff:        if (GetImageCLSID(IMAGE_TYPE_TIFF, &clsID) && clsID != GUID_NULL)        {            gdiRet = pImage->Save(lpstrPath, &clsID);        }        break;    case enumSaveImageType_png:        if (GetImageCLSID(IMAGE_TYPE_PNG, &clsID) && clsID != GUID_NULL)        {            gdiRet = pImage->Save(lpstrPath, &clsID);        }        break;    default:        break;    }    bRet = (gdiRet == Gdiplus::Ok ? TRUE : FALSE);Exit0:    if (pImage != NULL)    {        delete pImage;        pImage = NULL;    }    return bRet;}//////////////////////////////////////////////////////////////////////////

四、使用示例

KGdiplusImageMgr().SaveImage(m_hWnd, L".\\main.png");m_hWnd是一个窗口句柄



0 0
原创粉丝点击