• VS2010 使用GDI+创建图片水印的MFC程序


    首先配置好VS2010 的GDIplus的环境:
    http://www.hacktea8.com/read.php?tid-1489.html

    创建文件对话框的函数:
    【部分源码】
    //定义文件打开的方式
    CFileDialog fldlg(true,"","",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"图像文件|*.jpg|*.gif|*.jpeg|*.png|*.bmp||");
    if(fldlg.DoModal()==IDOK){
    CString szText=fldlg.GetPathName();
    m_FileName.SetWindowTextA(szText);
    if(m_pBmp!=NULL){
    //delete m_pBmp; new delete 成对出现 申请/释放
    m_pBmp=NULL;
    }
    m_pBmp=Bitmap::FromFile(szText.AllocSysString());
    Color bkClr(0,0,0);
    HBITMAP hBmp;
    m_pBmp->GetHBITMAP(bkClr,&hBmp);
    m_ImageDemo.SetBitmap(hBmp);
    szText.ReleaseBuffer();
    创建GDI+水印效果的函数
    【部分源码】
    UpdateData();
    CString szText;
    m_WaterText.GetWindowTextA(szText);
    if(!szText.IsEmpty()&&m_pBmp!=NULL){
    Graphics *pGraph=Graphics::FromImage(m_pBmp);
    Brush *pBrush=new SolidBrush(Color(255,0,0));
    Gdiplus::Font *pFont=new Gdiplus::Font(L"Arial",12);
    PointF ptf;
    ptf.X=m_OriginX;
    ptf.Y=m_OriginY;
    //确定字符长度
    int nLen=MultiByteToWideChar(CP_ACP,0,szText,-1,NULL,0);
    //在位图中输入字符串
    pGraph->DrawString(szText.AllocSysString(),nLen,pFont,ptf,pBrush);
    szText.ReleaseBuffer();
    Color clr;
    HBITMAP hBmp,hOldBmp;
    m_pBmp->GetHBITMAP(clr,&hBmp);
    hOldBmp=m_ImageDemo.SetBitmap(hBmp);
    if(hOldBmp){
    DeleteObject(hOldBmp);
    }
    delete pBrush;
    delete pFont;

    注:本人在做的时候遇到编译器兼容性问题【Debug和release 两个一个可以编译,而Debug不可以编译】
    所有输出均为最新。
    1> WaterPictureDlg.cpp
    1>d:\dev\vcdemo\waterpicture\waterpicture\waterpicturedlg.cpp(208): error C2660: “Gdiplus::GdiplusBase::operator new”: 函数不接受 3 个参数
    1>d:\dev\vcdemo\waterpicture\waterpicture\waterpicturedlg.cpp(209): error C2660: “Gdiplus::GdiplusBase::operator new”: 函数不接受 3 个参数
    1>d:\dev\vcdemo\waterpicture\waterpicture\waterpicturedlg.cpp(211): warning C4244: “=”: 从“UINT”转换到“Gdiplus::REAL”,可能丢失数据
    1>d:\dev\vcdemo\waterpicture\waterpicture\waterpicturedlg.cpp(212): warning C4244: “=”: 从“UINT”转换到“Gdiplus::REAL”,可能丢失数据
    1>
    1>生成失败。
    1>
    1>已用时间 00:00:00.15
    ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
    微软解决方法:
    生成时使用 GDI+ 的 Microsoft 基础类 (MFC) 应用程序的调试版本,您可能会收到类似于以下错误消息:
    错误 C2660: 新 Gdiplus::GdiplusBase::operator: 函数不带 3 个参数
    原因
    在调试版本中,MFC 定义预处理器扩展到的宏new运算符重载新运算符带有两个额外的参数。多余的参数是源文件名称和代码行号。MFC 可使用此信息对程序员在调试模式下时报告内存泄漏。这适用于的 MFC 类因为 MFC 提供的新接受多余的参数的重载。

    但是,此扩展完成后由预处理器,因为它会影响所有使用new运算符。如果在项目中使用了任何非 MFC 类,其new运算符也会扩展,即使没有合适的新重载可用在该类中。在 GDI+ 中所发生的情况,因此,您会收到一个编译时错误消息。
    替代方法
    要解决此问题,请选择下列方法之一:

    关闭预处理器扩展通过注释掉下面的源文件中的代码行:

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif

    注意: 此方法具有的缺点是不使用 MFC 中的功能,可帮助您跟踪内存分配和泄漏。
    GDI+ 使用重载为提供新和删除运算符通过编写一些代码,接受并丢弃的附加参数。可以将下面的代码演示了此方法,其粘贴到新的头文件并包括新的头文件,而不是 Gdiplus.h 文件。

    //// Ensure that GdiPlus header files work properly with MFC DEBUG_NEW and STL header files.

    #define iterator _iterator

    #ifdef _DEBUG

    namespace Gdiplus
    {
    namespace DllExports
    {
    #include <GdiplusMem.h>
    };

    #ifndef _GDIPLUSBASE_H
    #define _GDIPLUSBASE_H
    class GdiplusBase
    {
    public:
    void (operator delete)(void* in_pVoid)
    {
    DllExports::GdipFree(in_pVoid);
    }

    void* (operator new)(size_t in_size)
    {
    return DllExports::GdipAlloc(in_size);
    }

    void (operator delete[])(void* in_pVoid)
    {
    DllExports::GdipFree(in_pVoid);
    }

    void* (operator new[])(size_t in_size)
    {
    return DllExports::GdipAlloc(in_size);
    }

    void * (operator new)(size_t nSize, LPCSTR lpszFileName, int nLine)
    {
    return DllExports::GdipAlloc(nSize);
    }

    void operator delete(void* p, LPCSTR lpszFileName, int nLine)
    {
    DllExports::GdipFree(p);
    }

    };
    #endif // #ifndef _GDIPLUSBASE_H
    }
    #endif // #ifdef _DEBUG

    #include <gdiplus.h>
    #undef iterator
    //// Ensure that Gdiplus.lib is linked.
    #pragma comment(lib, "gdiplus.lib")

    【http://support.microsoft.com/kb/317799 微软原文】

    源码如下:
    WaterPicture
    原文:http://www.hacktea8.com/read.php?tid-1493-ds-1.html

  • 相关阅读:
    Flask简述
    1601. 救生艇
    1538. 卡牌游戏 II
    1604. 两数最大和
    1790. 旋转字符串II
    1540. 能否转换
    vs2012加载EntityFrameWork框架,连接Oracel
    MVC文件上传
    IIS发布程序,出现:请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理解决方案
    封装Socket.BeginReceive/EndReceive支持Timeout简介
  • 原文地址:https://www.cnblogs.com/zhongbin/p/2877840.html
Copyright © 2020-2023  润新知