精华内容
下载资源
问答
  • 精通GDI+编程

    2018-07-24 10:07:07
    第二章 GDI+编程基础 第三章 画笔和画刷 第四章 文本和字体 第五章 路径和区域 第六章 在GDI+中使用变换 第七章 GDI+的色彩变换 第八章 图像的基本处理 第九章 调整图像的色彩信息 第十章 图形的编码与解码 第十一章...
  • GDI编程

    千次阅读 2018-10-07 22:17:15
    1. GDI编程基本步骤

    1. GDI编程基本步骤
    在这里插入图片描述
    MFC OnPaint()函数中代码实现步骤

    	//获取DC
    		CPaintDC dc(this);
    	//创建GDI对象
    		//创建画刷
    		CBrush newBrush;
    		CBrush *pOldBrush;
    		newBrush.CreateSolidBrush(RGB(0,255,0));		
    		//创建画笔
    		CPen newPen;
    		CPen *pOldPen;
    		newPen.CreatePen(PS_SOLID,1,RGB(0,0,255));
    		//创建字体
    		CFont newFont;
    		CFont *pOldFont;
    		newFont.CreatePointFont(200,"宋体");
    	//把GDI对象写入DC
    		//将画刷写入DC
    		pOldBrush=dc.SelectObject(&newBrush);
    		//将画笔写入DC
    		pOldPen=dc.SelectObject(&newPen);
    		//将字体写入DC
    		pOldFont=dc.SelectObject(&newFont);
    	//绘图和字体输出
    		CRect rc;
    		GetClientRect(&rc);
    		dc.Rectangle(rc);
    		dc.TextOut(150,150,"画刷绿色,画笔蓝色");
    	//恢复画刷,画笔和字体
    		dc.SelectObject(pOldBrush);
    		dc.SelectObject(pOldPen);
    		dc.SelectObject(pOldFont);
    	//删除新建画刷,画笔和字体
    		newBrush.DeleteObject();
    		pOldBrush->DeleteObject();
    		newPen.DeleteObject();
    		pOldPen->DeleteObject();
    		newFont.DeleteObject();
    		pOldFont->DeleteObject();
    	//释放DC,析构函数直接释放
    
    展开全文
  • GDI+编程》电子书

    2018-07-04 11:04:26
    网上有一份,居然要12分,太坑人了,我搞5分就可以了,内容一样
  • VC++《精通GDI+编程》电子书教程,本书在介绍GDI+编程技术的同时,列举了大量的典型实例。通过这些实例,读者不仅可以更好地掌握GDI+编程的方法和技巧,还可以单一反三地将其应用到各类实际操作中。 清华大学出版社...
  • C#GDI 编程教程.doc

    2019-08-20 11:36:07
    C#GDI 编程教程,主要介绍使用C#进行图形图像编程基础,其中包括GDI+绘图基础、C#图像处理基础以及简单的图像处理技术。
  • 探索MFC GDI类的内部工作并提出替代方案
  • VC GDI编程源码实例集,有些还牵扯到动画效果,GDI在图像处理方面的优势还是相当大的,本实例集涉及到了多种图像编程的例子源码,比如坐标映射、画刷、GDI对象、显示位图资源、绘制图形等。
  • 精通gdi 编程 VC pdf

    2013-02-07 15:14:44
    精通gdi 编程 VC pdf版本 学习GDI+编程的方法技巧
  • GDI编程注意点-1

    2016-05-22 21:24:12
    博客对应资源,整理常见的GDI编程技巧和注意点,希望对大家有帮助。
  • GDI 编程基础简介

    2017-11-14 21:04:00
     在进行Windows编程时,可能经常会用到设备描述表的类型句柄,例如,最厂家的HDC,它就是图像设备描述类型句柄。因为GDI的绘图函数基本上都是有状态的,因此GDI所有的函数都要求一个这样的图形设备描述类型的句柄...

      今天准备重新对GDI的知识进行回顾一下,以便加深认识。

     

    一、GDI

      在进行Windows编程时,可能经常会用到设备描述表的类型句柄,例如,最厂家的HDC,它就是图像设备描述类型句柄。因为GDI的绘图函数基本上都是有状态的,因此GDI所有的函数都要求一个这样的图形设备描述类型的句柄——HDC。而一个图像设备描述表实际上就是对一种安装在机器上的图形卡的描述在使用句柄时,其实就是对具体的一种设备进行操作。对于GDI的任何函数的调用,这个设备的信息是需的。

      

      从本质上来说,提供指向任何GDI函数的HDC句柄,都是用来访问一个函数操作设备的重要信息。这就是需要一个图形描述表的原因。

      图形设备描述表要跟踪编程过程中任何可能改变的软件设置。比如,在GDI中被大量使用的字体、画笔、画刷、线、点、矩形等类型。GDI使用这些基本数据类型来绘制任何图形,即使使用的画笔颜色不是视频卡的默认颜色,那么设备描述表也会跟踪它。因此,图形设备描述表不仅是硬件的描述,而且还是记录和保存设置的信息库

     

    二、CDC类

      CDC类就是MFC把DC(设备描述环境)和一些GDI函数填充装到一起的一个集合。它是CObject的直接派生类。并且从CDC又派生出了许多其他类,如最常用的窗口客户区DC所对应的CClientDC类,OnPaint和OnDraw消息响应函数的输入参数中使用的CPaintDC类,图元文件对应的CMetaFileDC类和整个窗口所对应的CWindowDC类。CDC类中有许多成员函数,可以用来设备各种绘图环境、属性和参数,以及绘制各种图形和图像。

      常见的函数如下:

      (1)用于获取DC句柄的函数GetDC()

        每次调用GetDC函数所获得的DC,都是一个全新的临时默认DC,具有默认的绘图环境和设置。它不能用任何变量临时保存,而且GetDC后原来选入的各种GDI对象全部作废,原来设置的各种状态也失效,一切都要从头开始。

      (2)用于获取DC安全句柄的函数GetSafeHdc()

        其获得的DC在窗口的存在期间内一直是有效的。

      (3)用于释放DC的函数ReleaseDC()

    三、GDI对象

     3.1 画笔类

    使用构造函数创建

    CPen(

    int nPenStyle,

    int nWidth,

    COLORREF crColor

    用CreatePen函数创建画笔对象

    HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);

    用CETStockObject函数直接创创建画笔

    HGDIOBJ GetStockObject ( int fnObject )

    用CreatePenIndirect函数创建

    HPEN CreatePenIndirect( const LOGPEN * logopen );

    3.2 画刷类

    CBrush(

    int fnStyle

    COLOREF crColor

     

    HBRUSH CreateHatchBrush(int fnStyle, COLORREF crColor);

     

    GetStockObject()

     

    HBRUSH CreateBrushIndirect(CONST LOGBRUSH *lplb);

    typedef struct tagLOGBRUSH

    {

      UINT lbStyle;

      COLORREF lbColor;

      LONG lbHatch;

    } LOGBRUSH

     

    3.3 字体类

    3.4 点类

    typedef sturct tagPOINT

    {

      LONG x;

      LONG y;

    }POINT;

    3.5 大小类

    typedef struct tagSIZE

    {

      LONG cx;

      LONG cy;

    }SIZE;

     

     

     

     

     

    参考文章:

    1. Visual C++ 典型模块与项目实战大全

     

    没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。




        本文转自wenglabs博客园博客,原文链接:http://www.cnblogs.com/arxive/p/5560149.html ,如需转载请自行联系原作者
    展开全文
  • 用win32GDI位图编程实现推箱子小游戏,核心代码源于C语言控制台推箱子,相同的原理,不同的实现。
  • C# GDI编程C# GDI编程

    2011-04-15 14:45:54
    C# GDIC# GDIC# GDIC# GDIC# GDIC# GDIC# GDIC# GDI
  • GDI编程经典教程。相当好的东西和大家分享一下,希望对你会有帮助!
  • GDI编程 迷你CAD程序 MFC 源代码,可以选择图形,线条粗细,和颜色,以及保存,打开,工具栏,状态栏等,不懂可以问我
  • GDI编程基础GDI编程基础GDI编程基础GDI编程基础
  • C#_GDI 编程教程

    2014-09-08 06:54:56
    C#_GDI 编程教程 C#_GDI 编程教程
  • C# GDI GDI+编程小结

    2011-05-09 17:03:44
    GDI编程学习笔记总结,很不错的资源哦,对于想快速通览GDI编程或者想复习GDI编程的朋友很有用
  • GDI编程 GDI:Graphics Devices Interfacce GDI是显示设备与实际物理设备之间的桥梁,无需关心设备具体细节 就是一些与绘图相关的函数和一些数据结构和宏等组成的一个整体,它的作用就是实现了一对通用的图形对象,...

    GDI编程

    GDI:Graphics Devices Interfacce

    GDI是显示设备与实际物理设备之间的桥梁,无需关心设备具体细节

    就是一些与绘图相关的函数和一些数据结构和宏等组成的一个整体,它的作用就是实现了一对通用的图形对象,向屏幕、内存、打印机等设备进行绘图操作

    设备环境

    有很多别名:设备上下文,设备DC,(Device Context)简单的说就是程序中可以绘图的地方。

    GDI的几个区域

    屏幕区、窗口区、客户区


    如何在DC上绘图:

    1、获得设备DC;

    2、在DC上绘图

    有两种方式分别如下:

    //窗口绘制以及重绘case WM_PAINT:中,我们在此进行任意绘图的绘制
        PAINTSTRUCT ps; //结构体
        
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);//进行一些初始化的操作,返回DC句柄
            HPEN pen = CreatePen(PS_SOLID,3,RGB(255,0,0));//创建一个新的自定义颜色的画笔,如果不创建的话,就会使用系统默认的黑色画笔
    		HPEN holdpen = (HPEN)SelectObject(hdc,pen);//返回一个旧画笔
            tagPOINT pt;
            MoveTOEx(hdc,0,0,&pt);
            Lineo(hdc,100,100)
            SelectObject(hdc,holdpen);//将画笔选到dc句柄中
    		
            EndPaint(hWnd,&ps);//结束操作
            DeleteObject(pen);//由create创建的东西需要delete掉
    g_hWnd = NULL;//全局变量
    
    //在hWnd = CreateWindow();后面添加
    
    g_hWnd = hWnd ;
    
    HDC hDc = GetDc(g_hWnd);//客户区的DC
    HDC hDcWnd = GetWindowDC(g_hWnd); //窗口的DC
    
    //HBRUSH brush = CreateSolidBrush(RGB(255,0,0));//获得一个红色的画刷
    HBRUSH brush = (HBRUSH)GetStockObject(NULL_BRUSH);//获得一个透明画刷
    SelectObject(hDc,brush);
    Rectangle(hDc,0,0,50,50); //画一个矩形
    
    ReleaseDC(g_hWnd,hDc);//释放句柄,如果不释放的话,别的函数就无法使用这个dc

    展开全文
  • 用win32GDI函数编程实现推箱子小游戏,GDI自绘个性化界面
  • GDI编程-绘图

    2013-02-28 15:33:18
    GDI编程-绘图,方便大家学习GDI,其中的代码值得参考
  • GDI编程基础

    2013-01-08 14:07:00
    详细描述了GDI编程基础内容,并以实例讲解。
  • GDI编程绘图

    2012-11-24 12:01:44
    大学c#。net 编程绘图工具,比较简单 适合初学者
  • c#GDI+编程教程

    2018-12-20 12:16:07
    介绍使用C#进行图形图像编程基础,其中包括GDI+绘图基础、C#图像处理基础以及简单的图像处理技术。
  • GDI+编程
  • C# GDI编程

    2012-05-21 13:04:36
    一个简单的关于GDI图像处理的小程序,基于C#编程技术开发语言,可以简单的实现图像的选取,像素处理,转换的问题
  • 精通GDI编程

    2011-10-18 15:37:09
    GDI编程进行系统的阐述,是学习windows图像处理的好材料
  • 《精通GDI+编程》.PDF[含目录]

    热门讨论 2013-09-19 16:07:15
    2.3 从GDI编程到GDI+编程 2.4 GDI+程序的开发与项目分发 2.5 GDI+编程基本操作 2.6 本章小结 第3章 画笔和画刷 3.1 在GDI+中使用画笔 3.2 在GDI+中使用画刷 3.3 本章小结 第4章 文本和字体 4.1 在GDI+中使用字体 4.2...
  • MFC之GDI GDI+ 编程实例剖析

    千次阅读 2016-05-31 14:32:42
    GDIGDI+编程实例剖析 1.基本概念 GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows API(Application Programming Interface)的一个重要组成部分。它是Windows图形显示程序与实际...

    GDI和GDI+编程实例剖析



    1.基本概念   

        GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows API(Application Programming Interface)的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具体设备的细节,而只需在一个虚拟的环境(即逻辑设备)中进行操作。

    它的桥梁作用体现在:   

        (1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。为实现图形设备无关性,Windows 的绘图操作在一个设备描述表上进行。用户拥有自己的"逻辑坐标"系统,它独立于实际的物理设备,与"设备坐标"相对应。开发Windows应用程序时,程序员关心的是逻辑坐标,我们在逻辑坐标系上绘图,利用GDI将逻辑窗口映射到物理设备上。       (2)GDI能检测具体设备的能力,并依据具体的设备以最优方式驱动这些设备,完成真实的显示。

         GDI函数大致可分类为:

         -->设备上下文函数(如GetDC、CreateDC、DeleteDC);

         -->画线函数(如LineTo、Polyline、Arc)

         -->填充画图函数(如Ellipse、FillRect、Pie)

         -->画图属性函数(如SetBkColor、SetBkMode、SetTextColor)

         -->文本

         -->字体函数(如TextOut、GetFontData)

         -->位图函数(如SetPixel、BitBlt、StretchBlt)

         -->坐标函数(如DPtoLP、LPtoDP、ScreenToClient、ClientToScreen)

         -->映射函数(如SetMapMode、SetWindowExtEx、SetViewportExtEx)

         -->元文件函数(如PlayMetaFile、SetWinMetaFileBits)

         -->区域函数(如FillRgn、FrameRgn、InvertRgn)

         -->路径函数(如BeginPath、EndPath、StrokeAndFillPath)

         -->裁剪函数(如SelectClipRgn、SelectClipPath)等。   

        GDI虽然使程序员得到了一定程度的解脱,但是其编程方式仍很麻烦。譬如,显示一张位图,程序员需要进行"装入位图―读取位图文件头信息―启用设备场景―调色板变换"等一连串操作。而有了GDI+,这些问题便迎刃而解了。顾名思义,GDI+是GDI的增强版。它是微软在Windows 2000以后操作系统中提供的新接口,其通过一套部署为托管代码的类来展现,这套类被称为GDI+的"托管类接口"。

        GDI+主要提供了以下三类服务:   

        (1) 二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;   

        (2) 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。   

        (3) 文字显示:GDI+支持使用各种字体、字号和样式来显示文本。GDI接口是基于函数的,而GDI+是基于C++类的对象化的应用程序编程接口,因此使用起来比GDI要方便。   

     

       2.例程简述   单击此处下载本文例程源代码。   

        本文后续的讲解都基于这样的一个例子工程(例程的开发环境为Visual C++6.0,操作系统为Windows XP),它是一个基于对话框的MFC应用程序,包括2个父菜单:   

        (1) GDI   GDI父菜单下包括一个子菜单: ID:IDM_GDI_DRAW_LINE caption:画线单击事件:在窗口绘制正旋曲线   

        (2) GDI+   DIB位图父菜单下包括两个子菜单:

         -->a. ID:IDM_GDIP_DRAW_LINE caption:画线 单击事件:在窗口绘制正旋曲线

         -->b. caption:新增功能,其下又包括下列子菜单:

             (ⅰ)ID:IDM_Gradient_Brush caption:渐变画刷 单击事件:在窗口演示GDI+的渐变画刷功能

             (ⅱ)ID:IDM_Cardinal_Spline caption:基数样条  单击事件:在窗口演示GDI+的基数样条函数功能   

             (ⅲ)ID:IDM_Transformation_Matrix caption:变形和矩阵对象   单击事件:在窗口演示GDI+的变形和矩阵对象功能   

             (ⅳ)ID:IDM_Scalable_Region caption:可伸缩区域   单击事件:在窗口演示GDI+的可伸缩区域功能   

             (ⅴ)ID:IDM_IMAGE caption:图像   单击事件:在窗口演示GDI+的多种图像格式支持功能   

             (ⅵ)ID:IDM_Alpha_Blend caption:Alpha混合   单击事件:在窗口演示GDI+的Alpha混合功能   

             (ⅶ)ID:IDM_TEXT caption:文本   单击事件:在窗口演示GDI+的强大文本输出能力

        后续篇章将集中在对上述菜单单击事件消息处理函数的讲解,下面的代码是整个对话框类CGdiexampleDlg的消息映射:

    1. BEGIN_MESSAGE_MAP(CGdiexampleDlg, CDialog) //{{AFX_MSG_MAP(CGdiexampleDlg)   
    2. ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_COMMAND(IDM_GDI_DRAW_LINE, OnGdiDrawLine) ON_COMMAND(IDM_GDIP_DRAW_LINE, OnGdipDrawLine) ON_COMMAND(IDM_Gradient_Brush, OnGradientBrush) ON_COMMAND(IDM_Cardinal_Spline, OnCardinalSpline) ON_COMMAND(IDM_Transformation_Matrix, OnTransformationMatrix) ON_COMMAND(IDM_Scalable_Region, OnScalableRegion) ON_COMMAND(IDM_IMAGE, OnImage) ON_COMMAND(IDM_Alpha_Blend, OnAlphaBlend) ON_COMMAND(IDM_TEXT, OnText) //}}AFX_MSG_MAP END_MESSAGE_MAP()  

    3.GDI编程   "GDI"菜单下的"画线"子菜单单击事件消息处理函数的代码如下:

    1. void CGdiexampleDlg::OnGdiDrawLine() {  // TODO: Add your command handler code here    
    2. CClientDC dc(this);  //逻辑坐标与设备坐标变换  CRect rect;    
    3. GetClientRect(&rect);    
    4. dc.SetMapMode(MM_ANISOTROPIC);    
    5. dc.SetWindowOrg(0, 0);    
    6. dc.SetWindowExt(rect.right, rect.bottom);  dc.SetViewportOrg(0, rect.bottom / 2);  dc.SetViewportExt(rect.right, - rect.bottom);  //创建绘制正旋曲线的pen并将其选入设备上下文    
    7. CPen pen(PS_SOLID, 1, RGB(255, 0, 0));    
    8. HGDIOBJ oldObject = dc.SelectObject(pen.GetSafeHandle());  //绘制正旋曲线    
    9. dc.MoveTo(0, 0);    
    10. for (int i = 0; i < rect.right; i++)  {   dc.LineTo(i, 100 *sin(2 *(i / (rect.right / 5.0)) *PI));  }  //创建绘制x轴的pen并将其选入设备上下文    
    11. CPen penx(PS_SOLID, 1, RGB(0, 0, 255));  dc.SelectObject(penx.GetSafeHandle());  //绘制X轴    
    12. dc.MoveTo(0, 0);    
    13. dc.LineTo(rect.right, 0);  //恢复原先的pen  dc.SelectObject(oldObject);   
    14. }  

      单击这个按钮,会出现如图1所示的效果,我们来对此进行解读。

     图1 绘制正旋曲线

      前文提到,GDI编程需进行设备坐标和逻辑坐标的转化。而屏幕上的设备坐标通常会按客户坐标给出,客户坐标依赖于窗口的客户区域,其起始位置位于客户区域的左上角。为示区别,图2给出了设备坐标和用户逻辑坐标的示例。

     图2 设备坐标与逻辑坐标

      设备坐标与逻辑坐标的转换关系如下:

     

      公式中的<Xvorg, Yvorg>是设备空间中视口的原点,而< Xworg, Yworg >是逻辑空间中窗口的原点。 Xwext/Xvext和Ywext/Yvext分别是窗口与视口水平和垂直范围的比例。   因此,经过程序中的dc.SetWindowOrg (0,0) 和dc.SetViewportOrg (0,rect.bottom/2)语句我们设置了视口和窗口的原点;而经过程序中的dc.SetWindowExt (rect.right,rect.bottom) 和dc.SetViewportExt (rect.right,-rect.bottom) 语句我们设置了视口和窗口的范围。由于视口和窗口的纵坐标方向相反,设置视口的垂直范围为负值。这样我们得到了一个逻辑坐标原点为客户区水平方向最左边和垂直方向居中的坐标系,我们在这个坐标系上直接绘制正旋曲线,不需要再理睬Windows对话框客户区坐标了。   void CGdiexampleDlg::OnGdiDrawLine()函数中未指定逻辑设备和物理设备的映射模式,则为缺省的MM_TEXT。在这种模式下,一个逻辑单位对应于一个像素点。映射模式是GDI中的一个重要概念,其它的映射模式还有MM_LOENGLlSH、MM_HIENGLISH、MM_LOMETRIC和MM_HIMETRIC等。我们可以通过如下语句指定映射模式为MM_TEXT:

    1. dc.SetMapMode(MM_TEXT);  

      值得一提的是,从上述代码可以看出:在GDI编程中,几乎所有的操作都围绕设备上下文dc展开。的确,这正是GDI编程的特点!设备上下文是Windows 使用的一种结构,所有GDI操作前都需取得特定设备的上下文,函数中的CClientDC dc (this) 语句完成这一功能。   归纳可得,利用GDI进行图形、图像处理的一般操作步骤为:   1. 取得指定窗口的DC;   2. 确定使用的坐标系及映射方式;   3. 进行图形、图像或文字处理;   4. 释放所使用的DC。   4.GDI+编程   "GDI+"菜单下的"画线"子菜单单击事件消息处理函数的代码如下:

    1. void CGdiexampleDlg::OnGdipDrawLine() {  // TODO: Add your command handler code here    
    2. CClientDC dc(this);  //逻辑坐标与设备坐标变换  CRect rect;    
    3. GetClientRect(&rect);    
    4. dc.SetMapMode(MM_ANISOTROPIC);    
    5. dc.SetWindowOrg(0, 0);    
    6. dc.SetWindowExt(rect.right, rect.bottom);  dc.SetViewportOrg(0, rect.bottom / 2);  dc.SetViewportExt(rect.right, - rect.bottom);  //创建Graphics对象    
    7. Graphics graphics(dc);  //创建pen    
    8. Pen myPen(Color::Red);    
    9. myPen.SetWidth(1);  //画正旋曲线    
    10. for (int i = 0; i < rect.right; i++)  {   graphics.DrawLine(&myPen, i, 100 *sin(2 *(i / (rect.right / 5.0)) *PI), i + 1, 100 *sin(2 *((i + 1) / (rect.right / 5.0)) *PI));  }  //画X轴  
    11.   myPen.SetColor(Color::Blue);   
    12.  graphics.DrawLine(&myPen, 0, 0, rect.right, 0); }  

      由于我们使用的是Visual C++6.0而非VS.Net,我们需要下载微软的GDIPLUS支持包。在微软官方网站下载时需认证Windows为正版,我们可从这个地址下载:http://www.codeguru.com/code/legacy/gdi/GDIPlus.zip。一个完整的GDI+支持包至少包括如下文件:   (1)头文件:gdiplus.h   (2)动态链接库的.lib文件:gdiplus.lib   (3)动态链接库的.dll文件:gdiplus.dll   少了(1)、(2)程序不能编译,少了(3)程序能以共享DLL的方式编译但是不能运行,运行时找不到.dll文件。   为使得Visual C++6.0支持GDI+,我们需要在使用GDI+对象的文件的开头添加如下代码:

    1. #define UNICODE #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #endif #include "c:/gdiplus/includes/gdiplus.h" using namespace Gdiplus; #pragma comment(lib, "c://gdiplus//lib//gdiplus.lib")  

      在Visual C++中使用GDI+必须先进行GDI+的初始化,我们在CWinApp派生类的InitInstance函数中进行此项工作是最好的:

    1. / // CGdiexampleApp initialization BOOL CGdiexampleApp::InitInstance() {    
    2. AfxEnableControlContainer();  // Standard initialization  #ifdef _AFXDLL   Enable3dControls(); // Call this when using MFC in a shared DLL    
    3. #else     
    4. Enable3dControlsStatic(); // Call this when linking to MFC statically    
    5. #endif  //初始化gdiplus的环境  GdiplusStartupInput gdiplusStartupInput;  ULONG_PTR gdiplusToken;  // 初始化GDI+.  GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);    
    6. CGdiexampleDlg dlg;    
    7. m_pMainWnd = &dlg;    
    8. int nResponse = dlg.DoModal();    
    9. if (nResponse == IDOK){}    
    10. else if (nResponse == IDCANCEL){}  //关闭gdiplus的环境    
    11. GdiplusShutdown(gdiplusToken);    
    12. return FALSE; }  

      单击"GDI+"菜单下的"画线"子菜单,也会出现如图1所示的效果。观察void CGdiexampleDlg::OnGdipDrawLine() 函数,我们发现用GDI+进行图形、图像操作的步骤为:   (1)创建 Graphics 对象:Graphics 对象表示GDI+绘图表面,是用于创建图形图像的对象;   (2)使用 Graphics 对象绘制线条和形状、呈现文本或显示与操作图像。   Graphics 对象是GDI+的核心,GDI中设备上下文dc和Graphics 对象的作用相似,但在GDI中使用的是基于句柄的编程模式,而GDI+中使用的则是基于对象的编程模式。Graphics封装了GDI+ 绘图面,而且此类无法被继承,它的所有成员函数都不是虚函数。   下面,我们来逐个用实际代码实现GDI+的新增功能,这些新增功能包括:渐变的画刷(Gradient Brushes)、基数样条函数(Cardinal Splines)、持久的路径对象(Persistent Path Objects)、变形和矩阵对象(Transformations &Matrix Object)、可伸缩区域(Scalable Regions)、Alpha混合(Alpha Blending)和丰富的图像格式支持等。 渐变的画刷   GDI+提供了用于填充图形、路径和区域的线性渐变画刷和路径渐变画刷。   线性渐变画刷使用渐变颜色来填充图形。   当用路径渐变画刷填充图形时,可指定从图形的一部分移至另一部分时画刷颜色的变化方式。例如,我们可以只指定图形的中心颜色和边缘颜色,当画刷从图形中间向外边缘移动时,画刷会逐渐从中心颜色变化到边缘颜色。

    1. void CGdiexampleDlg::OnGradientBrush() {  // TODO: Add your command handler code here  
    2.   CClientDC dc(this);    
    3. CRect rect;    
    4. GetClientRect(&rect);  //创建Graphics对象  Graphics graphics(dc);  //创建渐变画刷  LinearGradientBrush lgb(Point(0, 0), Point(rect.right, rect.bottom), Color::Blue, Color::Green);  //填充    
    5. graphics.FillRectangle(&lgb, 0, 0, rect.right, rect.bottom); }  

      本程序使用线性渐变画刷,当画刷从客户区左上角移向客户区右下角的过程中,颜色逐渐由蓝色转变为绿色。

     图3 GDI+渐变画刷

      基数样条函数   GDI+支持基数样条,基数样条指的是一连串单独的曲线,这些曲线连接起来形成一条较大的曲线。样条由点(Point结构体)的数组指定,并通过该数组中的每一个点。基数样条平滑地穿过数组中的每一个点(不出现尖角),因此比用直线连接创建的路径精确。

    1. void CGdiexampleDlg::OnCardinalSpline() {  // TODO: Add your command handler code here  
    2.   CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);    
    3. Point points[] =  {     
    4. Point(0, 0),   
    5. Point(100, 200), Point(200, 0), Point(300, 200), Point(400, 00)  };  //直接画线    
    6. for (int i = 0; i < 4; i++)  {   graphics.DrawLine(&Pen(Color::Blue, 3), points[i], points[i + 1]);  }  //利用基数样条画线  
    7.   graphics.DrawCurve(&Pen(Color::Red, 3), points, 5); }  

      图4演示了直接连线和经过基数样条平滑拟合后的线条的对比,后者的曲线(Curve)没有尖角。这个工作我们在中学的数学课上把离散的点连接成曲线时做过。

     图4 GDI+基数样条

    持久的路径对象   在GDI中,路径隶属于一个设备上下文,一旦设备环境指针超过它的生存期,路径也会被删除。利用GDI+,可以创建并维护与Graphics对象分开的GraphicsPath 对象,它不依赖于Graphics对象的生存期。   变形和矩阵对象   GDI+提供了Matrix对象,它是一种可以使变形(旋转、平移、缩放等) 简易灵活的强大工具,Matrix对象需与要被变形的对象联合使用。对于GraphicsPath类,我们可以使用其成员函数Transform接收Matrix参数用于变形。

    1. void CGdiexampleDlg::OnTransformationMatrix() {  // TODO: Add your command handler code here  
    2.   CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);    
    3. GraphicsPath path;    
    4. path.AddRectangle(Rect(250, 20, 70, 70));  graphics.DrawPath(&Pen(Color::Black, 1), &path); // 在应用变形矩阵之前绘制矩形  // 路径变形   
    5.  Matrix matrix1, matrix2;    
    6. matrix1.Rotate(45.0f); //旋转顺时针45度  path.Transform(&matrix1); //应用变形  graphics.DrawPath(&Pen(Color::Red, 3), &path);  matrix2.Scale(1.0f, 0.5f); //转化成为平行四边形法则  path.Transform(&matrix2); //应用变形  graphics.DrawPath(&Pen(Color::Blue, 3), &path); }  

      图5演示了正方形经过旋转和拉伸之后的效果:黑色的为原始图形,红色的为旋转45度之后的图形,蓝色的为经过拉伸为平行四边形后的图形。

     图5 GDI+变形和矩阵对象

      可伸缩区域   GDI+通过对区域(Region)的支持极大地扩展了GDI。在GDI 中,区域存储在设备坐标中,可应用于区域的唯一变形是平移。但是在GDI +中,区域存储在全局坐标(世界坐标)中,可对区域利用变形矩阵进行变形(旋转、平移、缩放等)。

    1. void CGdiexampleDlg::OnScalableRegion() {  // TODO: Add your command handler code here  CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);  //创建GraphicsPath  GraphicsPath path;  path.AddLine(100, 100, 150, 150);  path.AddLine(50, 150, 150, 150);  path.AddLine(50, 150, 100, 100);  //创建Region  Region region(&path);  //填充区域  graphics.FillRegion(&SolidBrush(Color::Blue), ®ion);  //区域变形    
    2. Matrix matrix;    
    3. matrix.Rotate(10.0f); //旋转顺时针20度  matrix.Scale(1.0f, 0.3f); //拉伸  region.Transform(&matrix); //应用变形  //填充变形后的区域    
    4. graphics.FillRegion(&SolidBrush(Color::Green), ®ion); }  

      上述程序中以蓝色填充一个三角形区域,接着将此区域旋转和拉伸,再次显示,其效果如图6。

     图6 GDI+区域变形

    丰富的图像格式支持   GDI +提供了Image、Bitmap 和Metafile 类,方便用户进行图像格式的加载、操作和保存。GDI+支持的图像格式有BMP、GIF、JPEG、EXIF、PNG、TIFF、ICON、WMF、EMF等,几乎涵盖了所有的常用图像格式。

    1. void CGdiexampleDlg::OnImage() {  // TODO: Add your command handler code here    
    2. CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);  Image image(L "d://1.jpg");  //在矩形区域内显示jpg图像  Point destPoints1[3] =  {   Point(10, 10), Point(220, 10), Point(10, 290)  };  graphics.DrawImage(&image, destPoints1, 3);  //在平行四边形区域内显示jpg图像    
    3. Point destPoints2[3] =  {   Point(230, 10), Point(440, 10), Point(270, 290)  };  graphics.DrawImage(&image, destPoints2, 3); }  

      上述程序将D盘根目录下文件名为"1.jpg"的jpg图像以矩阵和平行四边形两种方式显示,效果如图7。

     图7 GDI+多种图像格式支持

      由此我们可以看出,GDI+在图像显示和操作方面的确比GDI简单许多。回忆我们在《Visual C++中DDB与DIB位图编程全攻略》一文中所介绍的用GDI显示位图的方式,其与GDI+图像处理的难易程度真是有天壤之别。 Alpha混合   Alpha允许将两个物体混合起来显示,在3D气氛和场景渲染等方面有广泛应用。它能"雾化"图像,使得一个图像着色在另一个半透明的图像上,呈现一种朦胧美。我们知道,一个像素可用R,G,B三个维度来表示,我们可以再加上第4个即:Alpha维度(channel),表征透明程度。

    1. void CGdiexampleDlg::OnAlphaBlend() {  // TODO: Add your command handler code here    
    2. CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);  //创建ColorMatrix  ColorMatrix ClrMatrix =  {     
    3. 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, 0.5f, 0.0f,   0.0f, 0.0f, 0.0f, 0.0f, 1.0f  };  //将ColorMatrix赋给  
    4. ImageAttributes  ImageAttributes ImgAttr;  ImgAttr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);  //在矩形区域内显示jpg图像    
    5. Image img1(L "d://1.jpg");    
    6. Point destPoints1[3] =  {   Point(10, 10), Point(220, 10), Point(10, 290)  };  graphics.DrawImage(&img1, destPoints1, 3);  //Alpha混合    
    7. Image img2(L "d://2.jpg");    
    8. int width, height;    
    9. width = img2.GetWidth();    
    10. height = img2.GetHeight();    
    11. graphics.DrawImage(&img2, RectF(10, 10, 210, 280), 0, 0, width, height,UnitPixel, &ImgAttr);  //在平行四边形区域内显示jpg图像    
    12. Point destPoints2[3] =  {   Point(230, 10), Point(440, 10), Point(270, 290)  };  graphics.DrawImage(&img1, destPoints2, 3);  //Alpha混合    
    13. graphics.DrawImage(&img2, destPoints2, 3, 0, 0, width, height, UnitPixel,&ImgAttr); }  

      上述程序中将D盘根目录下文件名为"1.jpg"的图像以矩阵和平行四边形两种方式显示,然后将文件名为为"2.jpg"的图像与之进行混合,其效果如图8。

     图8 GDI+ Alpha混合

      为了能进行Alpha混合,我们需要使用ImageAttributes类和ColorMatrix矩阵,ImageAttributes可以进行颜色、灰度等调整从而达到控制图像着色方式的目的。ColorMatrix是ImageAttributes类大多数函数的参数,它包含了Alpha、Red、Green、Blue维度的值,以及另一维w,顺序为RGBaw。   CGdiexampleDlg::OnAlphaBlend()函数中ColorMatrix的实例ClrMatrix中元素(4,4)的值为0.5,表示Alpha度的值为0.5(即半透明)。在ColorMatrix中,元素(5,5)的值恒定为1.0。我们把ClrMatrix的元素(0,0)修改为0.0,即使得图像2.jpg的红色维度全不显示,再看效果,为图9。列位读者,我们以前在豪杰超级解霸中调整R,G,B值从而控制图像输出颜色的时候,调的就是这个东东!图9的效果很像破旧彩色电视机,红色电子枪"嗝"了。刚大学毕业时,俺那个叫穷啊,就买了这么个电视机,还看得很爽,真是往事不堪回首!

     图9 GDI+中的ColorMatrix

    强大的文字输出   GDI+拥有极其强大的文字输出处理能力,输出文字的颜色、字体、填充方式都可以直接作为Graphics类DrawString成员函数的参数进行设置,其功能远胜过GDI设备上下文的TextOut函数。

    1. void CGdiexampleDlg::OnText() {  // TODO: Add your command handler code here    
    2. CClientDC dc(this);  //创建Graphics对象  Graphics graphics(dc);  //创建20号"楷体"字体  FontFamily fontFamily1(L "楷体_GB2312"); // 定义"楷体"字样    
    3. Font font1(&fontFamily1, 20, FontStyleRegular, UnitPoint);  //定义输出UNICODE字符串    
    4. WCHAR string[256];    
    5. wcscpy(string, L "天极网的读者朋友,您好!");  //以蓝色画刷和20号"楷体"显示字符串    
    6. graphics.DrawString(string, (INT)wcslen(string), &font1, PointF(30, 10),&SolidBrush(Color::Blue));  //定义字符串显示画刷  LinearGradientBrush linGrBrush(Point(30, 50), Point(100, 50), Color(255, 255,0, 0), Color(255, 0, 0, 255));  //以线性渐变画刷和创建的20号"楷体"显示字符串    
    7. graphics.DrawString(string, (INT)wcslen(string), &font1, PointF(30, 50),&linGrBrush);  //创建20号"华文行楷"字体    
    8. FontFamily fontFamily2(L "华文行楷"); // 定义"楷体"字样    
    9. Font font2(&fontFamily2, 20, FontStyleRegular, UnitPoint);  //以线性渐变画刷和20号"华文行楷"显示字符串    
    10. graphics.DrawString(string, (INT)wcslen(string), &font2, PointF(30, 90),&linGrBrush);  //以图像创建画刷    
    11. Image image(L "d://3.jpg");    
    12. TextureBrush tBrush(&image);  //以图像画刷和20号"华文行楷"显示字符串    
    13. graphics.DrawString(string, (INT)wcslen(string), &font2, PointF(30, 130),&tBrush);  //创建25号"华文中宋"字体    
    14. FontFamily fontFamily3(L "华文中宋"); // 定义"楷体"字样    
    15. Font font3(&fontFamily2, 25, FontStyleRegular, UnitPoint);  //以图像画刷和20号"华文行楷"显示字符串  graphics.DrawString(string, (INT)wcslen(string), &font3, PointF(30, 170),&tBrush); }  

      上述代码的执行效果如图10所示,字体、颜色和填充都很丰富!

     图10 GDI+文本输出

    5.GDI与GDI+的比较   GDI+相对GDI而言主要在编程方式上发生了巨大的改变。   GDI的核心是设备上下文,GDI函数都依赖于设备上下文句柄,其编程方式是基于句柄的;GDI+无需时刻依赖于句柄或设备上下文,用户只需创建一个Graphics 对象,就可以用面向对象的方式调用其成员函数进行图形操作,编程方式是基于对象的。   GDI在使用设备上下文绘制线条之前,必须先调用SelectObject 以使钢笔对象和设备上下文关联。其后,在设备上下文中绘制的所有线条均使用该钢笔,直到选择另一支不同的钢笔为止。CGdiexampleDlg::OnGdiDrawLine函数中的下列语句完成的就是这个功能:

    1. //创建绘制正旋曲线的pen并将其选入设备上下文   
    2. CPen pen(PS_SOLID,1,RGB(255,0,0));   
    3. HGDIOBJ oldObject = dc.SelectObject(pen.GetSafeHandle()); … //创建绘制x轴的pen并将其选入设备上下文 CPen penx  
    4. (PS_SOLID,1,RGB(0,0,255)); dc.SelectObject(penx.GetSafeHandle()); … //恢复原先的pen dc.SelectObject(oldObject);  

      但是,在GDI+中,只需将Pen对象直接作为参数传递给Graphics类的DrawLine等方法即可,而不必使Pen对象与Graphics对象关联,例如CGdiexampleDlg::OnGdipDrawLine函数中的下列语句:

    1. Pen myPen(Color::Red); myPen.SetWidth(1); … graphics.DrawLine(&myPen,i,100*sin(2*(i/(rect.right/5.0))*PI), i+1,100*sin(2*((i+1)/(rect.right/5.0))*PI)); … graphics.DrawLine(&myPen,0,0,rect.right,0);  

      GDI中有当前位置的概念,所以在使用GDI绘制线条前应该先使用MoveTo移动当前位置,再使用LineTo画线,例如:

    1. //绘制正旋曲线 dc.MoveTo(0,0) ;   
    2. for(int i=0;i<rect.right;i++) {  dc.LineTo(i,100*sin(2*(i/(rect.right/5.0))*PI)); }  

      而GDI+中则没有当前位置的概念,画线函数中可以直接指定起点和终点,例如:

    1. graphics.DrawLine(&myPen,0,0,rect.right,0);  

      6.结论   鉴于GDI+良好的易用性和其具有的强大功能,我们建议尽快抛弃GDI编程方式,因为我们没有必要将时间浪费在无意义的重复代码的设计上。GDI+对GDI的增强,某种意义上类似于MFC对Windows API的整理和封装。作为一种良好的"生产工具",它必将大大地促进开发时的"生产力"。

    推荐一个比较好的GDI+开发指导教程pdf格式。文档共计40页。非常好的讲解了GDI+绘图的所有方法(内涵绘制各种曲线图像的源代码及运行视图,以及对比GDI的区别详细说明)。是本GDI+绘图入门及深入学习的不二良品

    下载地址: http://download.csdn.net/download/i_likechard/9973218



    转自:http://dev.yesky.com/255/2190255.shtml

    展开全文
  • mfc gdi编程实例

    2011-05-19 20:47:23
    mfc中直线 多段线 及其选中删除相关代码 字体设置 颜色设置
  • windows gdi编程

    2015-01-12 17:26:00
    一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以设备相关的格式和具体的设备打交道。  2、DC (Device Context):设备描述表(设备上下文),是一种Windows数据结构,包括了

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,425
精华内容 8,970
关键字:

gdi编程