MFC自绘-WzdImage图像类

最近开始学习MFC自绘,自绘要有比较好的效果需要支持图像绘制,那就从图像类开始,那就用GDI+弄一个图像类。GDI(Graphics Device Interface)图形设备接口,处理所有Windows程序的图形输出。GDI+是以前版本GDI的继承者,对GDI进行了优化并添加了许多新的功能,只需调用GDI+库输出的类的一些方法即可完成图形操作。
头文件:

#include <GdiPlus.h>

class CWzdImage
{
protected:
    Gdiplus::Image* m_pImage;            // 图片对象
    TCHAR m_strImageName[MAX_PATH];      // 图片名称

public:
    CWzdImage();            // 构造函数
    virtual ~CWzdImage();   // 析构函数

    bool IsNull();     // 是否加载
    int GetWidth();    // 获取宽度
    int GetHeight();   // 获取高度

    bool DestroyImage();    // 销毁图片

    // 加载图片
    bool LoadImage(LPCTSTR pszFileName);
    bool LoadImage(HINSTANCE hInstance, LPCTSTR pszResourceName);

    // 绘画图像
    bool DrawImage(CDC* pDC, int nWndX, int nWndY);
    bool DrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth, int nWndHeight);
    bool DrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth, int nWndHeight,
                  int nImgX, int nImgY);
    bool DrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth, int nWndHeight,
                  int nImgX, int nImgY, int nImgWidth, int nImgHeight);

    // 透明绘画
    bool AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, BYTE cbAlphaDepth);
    bool AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
                       int nWndHeight, BYTE cbAlphaDepth);
    bool AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
                       int nWndHeight,int nImgX, int nImgY, BYTE cbAlphaDepth);
    bool AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
                       int nWndHeight,int nImgX, int nImgY, int nImgWidth, int nImgHeight, BYTE cbAlphaDepth);
};

使用GDI+必须包含GdiPlus.h头文件,同时必须添加Gdiplus.lib静态库。另外初始化过程:

    GdiplusStartupInput input;
    GdiplusStartup(&m_GdiplusToken,&input,NULL);

释放过程都是必要的。

    GdiplusShutdown(m_GdiplusToken);

Gdiplus::Image* m_pImage:保存图像信息。
IsNull():判断是否有图像信息。
LoadImage():两种加载图片方式:

  • 一种调用Gdiplus::Image::FromFile()。
  • 一种调用了FindResource()系列函数。再通过Gdiplus::Image::FromStream()读入数据。

DrawImage():四种普通画图方式:

  • 在图片指定点开始(nWndX, nWndY)画一次图。
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)画整幅图。
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)从图片的指定点(nImgX, nImgY)画一次图。
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)用图片的指定区域(nImgX, nImgY,nImgWidth, nImgHeight)画一次图。

AlphaDrawImage():四种透明绘图方式(必须在有背景的情况下):

  • 从窗口指定点(nWndX, nWndY)开始以透明度(cbAlphaDepth)画一次图
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)以透明度(cbAlphaDepth)画整幅图。
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)从图片的指定点(nImgX, nImgY)以透明度(cbAlphaDepth)画一次图。
  • 在窗口指定区域(nWndX, nWndY,nWndWidth, nWndHeight)用图片的指定区域(nImgX, nImgY,nImgWidth, nImgHeight)以透明度(cbAlphaDepth)画一次图。

实现代码:

#include "stdafx.h"
#include "WzdImage.h"

// 构造函数
CWzdImage::CWzdImage()
: m_pImage(NULL)
{
    memset(m_strImageName, 0 ,sizeof(m_strImageName));
}

// 析构函数
CWzdImage::~CWzdImage()
{
    DestroyImage();
}

// 是否加载
bool CWzdImage::IsNull()
{
    if (NULL == m_pImage) return true;
    if (m_pImage->GetLastStatus() != Gdiplus::Ok) return true;

    return false;
}

// 获取宽度
int CWzdImage::GetWidth()
{
    if (IsNull()) return 0;

    return m_pImage->GetWidth();
}

// 获取高度
int CWzdImage::GetHeight()
{
    if (IsNull()) return 0;

    return m_pImage->GetHeight();
}

// 销毁图片
bool CWzdImage::DestroyImage()
{
    if (m_pImage!=NULL)
    {
        delete m_pImage;
        m_pImage = NULL;
    }

    return true;
}

// 加载图片
bool CWzdImage::LoadImage(LPCTSTR pszFileName)
{
    if (NULL != m_pImage) return false;

    // 加载文件
    CT2CW strFileName(pszFileName);
    m_pImage = Gdiplus::Image::FromFile((LPCWSTR)strFileName);

    if ((NULL == m_pImage) || (Gdiplus::Ok != m_pImage->GetLastStatus()))
    {
        DestroyImage();
        return false;
    }

    return true;
}

// 加载图片
bool CWzdImage::LoadImage(HINSTANCE hInstance, LPCTSTR pszResourceName)
{
    if (NULL != m_pImage) return false;

    // 查找资源
    HRSRC hResource = FindResource(hInstance, pszResourceName, _T("IMAGE"));
    if (NULL == hResource) return false;

    // 读取资源
    DWORD dwImageSize = SizeofResource(hInstance, hResource);
    LPVOID pImageBuffer = LoadResource(hInstance, hResource);

    IStream * pIStream = NULL;
    if (S_OK != CreateStreamOnHGlobal(NULL, TRUE, &pIStream))
    {
        return false;
    }

    // 写入数据
    pIStream->Write(pImageBuffer, dwImageSize, NULL);
    m_pImage= Gdiplus::Image::FromStream(pIStream);

    pIStream->Release();

    if ((NULL == m_pImage) || (Gdiplus::Ok != m_pImage->GetLastStatus()))
    {
        return false;
    }

    return true;
}

// 绘画图像: 从窗口指定点(nWndX,nWndY)开始画一次图
bool CWzdImage::DrawImage(CDC* pDC, int nWndX, int nWndY)
{
    int nImageWidth = m_pImage->GetWidth();
    int nImageHeight = m_pImage->GetHeight();

    return DrawImage(pDC, nWndX, nWndY, nImageWidth,
        nImageHeight, 0, 0, nImageWidth, nImageHeight);
}

// 绘画图像: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)画整幅图
bool CWzdImage::DrawImage( CDC* pDC, int nWndX, int nWndY, int nWndWidth, int nWndHeight)
{
    return DrawImage(pDC, nWndX, nWndY, nWndWidth,
        nWndHeight, 0, 0, GetWidth(), GetHeight());
}

// 绘画图像: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)从图片的指定点
// (nImgX,nImgY)画一次图
bool CWzdImage::DrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
     int nWndHeight, int nImgX, int nImgY)
{
    return DrawImage(pDC, nWndX, nWndY, nWndWidth,
        nWndHeight, nImgX, nImgY, nWndWidth, nWndHeight);
}

// 绘画图像: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)用图片的指定区域
// (nImgX,nImgY,nImgWidth,nImgHeight)画一次图
bool CWzdImage::DrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
     int nWndHeight, int nImgX, int nImgY, int nImgWidth, int nImgHeight)
{
    if (NULL == m_pImage || NULL == pDC) return false;

    //创建屏幕
    Gdiplus::Graphics graphics(pDC->GetSafeHdc());

    //构造位置
    Gdiplus::RectF rcDrawRect;
    rcDrawRect.X = (Gdiplus::REAL)nWndX;
    rcDrawRect.Y = (Gdiplus::REAL)nWndY;
    rcDrawRect.Width = (Gdiplus::REAL)nWndWidth;
    rcDrawRect.Height = (Gdiplus::REAL)nWndHeight;

    //绘画图像
    graphics.DrawImage(m_pImage, rcDrawRect, (Gdiplus::REAL)nImgX, (Gdiplus::REAL)nImgY,
        (Gdiplus::REAL)nImgWidth, (Gdiplus::REAL)nImgHeight, Gdiplus::UnitPixel);

    return true;
}

// 透明绘画: 从窗口指定点(nWndX,nWndY)开始以透明度(cbAlphaDepth)画一次图
bool CWzdImage::AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, BYTE cbAlphaDepth)
{
    int nImageWidth = m_pImage->GetWidth();
    int nImageHeight = m_pImage->GetHeight();

    return AlphaDrawImage(pDC, nWndX, nWndY, nImageWidth,
        nImageHeight, 0, 0, nImageWidth, nImageHeight, cbAlphaDepth);
}

// 透明绘画: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)以透明度
//(cbAlphaDepth)画整幅图
bool CWzdImage::AlphaDrawImage( CDC* pDC, int nWndX, int nWndY, int nWndWidth, 
     int nWndHeight, BYTE cbAlphaDepth)
{
    return AlphaDrawImage(pDC, nWndX, nWndY, nWndWidth,
        nWndHeight, 0, 0, GetWidth(), GetHeight(), cbAlphaDepth);
}

// 透明绘画: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)从图片的指定点
// (nImgX,nImgY)以透明度(cbAlphaDepth)画一次图
bool CWzdImage::AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
 int nWndHeight, int nImgX, int nImgY, BYTE cbAlphaDepth)
{
    return AlphaDrawImage(pDC, nWndX, nWndY, nWndWidth, nWndHeight,
        nImgX, nImgY, nWndWidth, nWndHeight, cbAlphaDepth);
}

// 透明绘画: 在窗口指定区域(nWndX,nWndY,nWndWidth,nWndHeight)用图片的指定区域
// (nImgX,nImgY,nImgWidth,nImgHeight)以透明度(cbAlphaDepth)画一次图
bool CWzdImage::AlphaDrawImage(CDC* pDC, int nWndX, int nWndY, int nWndWidth,
 int nWndHeight, int nImgX, int nImgY, int nImgWidth, int nImgHeight, BYTE cbAlphaDepth)
{
    //加载判断
    ASSERT(m_pImage!=NULL);
    if (m_pImage==NULL) return false;

    //创建屏幕
    ASSERT(pDC!=NULL);
    Gdiplus::Graphics graphics(pDC->GetSafeHdc());

    //构造位置
    Gdiplus::RectF rcDrawRect;
    rcDrawRect.X=(Gdiplus::REAL)nWndX;
    rcDrawRect.Y=(Gdiplus::REAL)nWndY;
    rcDrawRect.Width=(Gdiplus::REAL)nWndWidth;
    rcDrawRect.Height=(Gdiplus::REAL)nWndHeight;

    //透明矩阵
    Gdiplus::ColorMatrix Matrix=
    {
        1.0f,0.0f,0.0f,0.0f,0.0f,
        0.0f,1.0f,0.0f,0.0f,0.0f,
        0.0f,0.0f,1.0f,0.0f,0.0f,
        0.0f,0.0f,0.0f,cbAlphaDepth/255.0f,0.0f,
        0.0f,0.0f,0.0f,0.0f,1.0f
    };

    //设置属性
    Gdiplus::ImageAttributes Attributes;
    Attributes.SetColorMatrix(&Matrix,Gdiplus::ColorMatrixFlagsDefault, 
                             Gdiplus::ColorAdjustTypeBitmap);

    //绘画图像
    graphics.DrawImage(m_pImage,rcDrawRect,(Gdiplus::REAL)nImgX,(Gdiplus::REAL)nImgY,
    (Gdiplus::REAL)nImgWidth,(Gdiplus::REAL)nImgHeight,Gdiplus::UnitPixel,&Attributes);

    return true;
}

猜你喜欢

转载自blog.csdn.net/wizardtoh/article/details/47857509