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

(1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。

为实现图形设备无关性,Windows的绘图操作在一个设备描述表上进行。用户拥有自己的“逻辑坐标”系统,它独立于实际的物理设备,与“设备坐标”相对应。开发Windows应用程序时,程序员关心的是逻辑坐标,我们在逻辑坐标系上绘图,利用GDI将逻辑窗口映射到物理设备上。

(2)GDI能检测具体设备的能力,并依据具体的设备以最优方式驱动这些设备,完成真实的显示。

GDI函数大致可分类为:

GDI虽然使程序员得到了一定程度的解脱,但是其编程方式仍很麻烦。譬如,显示一张位图,程序员需要进行“装入位图 | 读取位图文件头信息 | 启用设备场景 | 调色板变换”等一连串操作。而有了GDI+,这些问题便迎刃而解了。

GDI+:GDI+是GDI的后续版本,最早于2001年随WinXP一起推出,后来又被包装进.NET框架的托管类库中,成为.NET中窗体绘图的主要工具。

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

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

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

(3)文字显示:GDI+支持使用各种字体、字号和样式来显示文本。

GDI接口是基于函数的,而GDI+是基于C++ OO的编程接口,因此使用起来比GDI要方便。因为GDI+实际上是GDI的封装和扩展,所以执行效率一般要低于GDI。

使用GDI时,经常需要将PEN、BRUSH等GDI对象选入DC,并需要保存旧的GDI对象,然后进行一些绘图操作。此时调用的绘图函数都是使用这些新选入的PEN、BRUSH,绘图完成之后再把旧的GDI对象重新选回DC,这称之为“状态模式”。而GDI+不是这样,GDI+只是将PEN、BRUSH等对象作为参数传递给绘图函数,它们只影响这一次的绘制,下次再调用绘图函数,可以将新的PEN、BRUSH传入给绘图函数,这称为“无状态模式”。与GDI相比,GDI+的编程模式发生了改变。

1、DC与Graphics

DC是GDI的核心,Graphics对象是GDI+的核心。DC和Graphics对象的作用相似,但使用句柄的编程模式和使用Graphics对象的面向对象的编程模型之间,存在一些基本的差异。

Graphics对象(像DC一样)与屏幕上的特定窗口关联,并具有指定如何绘制项目的属性(如 SmoothingMode 和 TextRenderingHint)。但Graphics 对象不受笔、刷、路径、图像或字体的约束,这与DC不同。例如,使用DC画线之前,必须先调用SelectObject以使笔对象和DC关联,即将笔选入DC中。之后的画线操作均使用该笔,直到选择另一支不同的笔为止。在GDI+中,将Pen对象作为参数传递给Graphics类的DrawLine方法。可以在一系列的 DrawLine 调用中,使用不同的Pen对象,而不必将给定的Pen对象与Graphics对象关联。

2、以画线为例

无论是GDI还是GDI+,都有API和MFC封装类两种使用方式。下面每个示例都从点(20, 10)到点(200, 100)绘制一条宽为3 的红色线条。

(1)GDI API

(2)GDI MFC

(3)GDI+ API

(4)GDI+ MFC

3、方法重载

许多GDI+方法都是重载的,这与MFC封装后的GDI类似。例如,DrawLine的重载方法有:

4、绘制和填充

GDI有一个Rectangle函数,可一步完成绘制轮廓和填充矩形内部。轮廓由当前选定的笔绘制,而内部则由当前选定的刷来填充。 GDI+使用Graphics类的DrawRectangle方法将 Pen对象作为参数绘制轮廓,使用Graphics类FillRectangle方法将Brush对象作为参数填充内部。

5、构造区域

GDI提供几种用于创建区域的函数(在MFC中,被封装在CRng类里):CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn 和CreatePolyPolygonRgn。你或许希望GDI+中的Region类也有类似的构造函数,将矩形、椭圆、圆角矩形和多边形作为参数接收,但事实并非如此。GDI+中的Region类提供一个接收Rectangle 对象的构造函数和另一个接收GraphicsPath对象的构造函数。如果想基于椭圆、圆角矩形或多边形构造区域,可以通过创建一个GraphicsPath对象(可包含椭圆的对象等),然后将其传递至Region构造函数来轻松实现。

路径(path)是一系列相互连接的直线和曲线,由许多不同类型的点所构成,用于表示复杂的不规则图形,也叫做图形路径(graphics path)。路径可以被画轮廓和填充,也可以用于创建区域和路径渐变刷等。在 GDI+中,路径由图形路径类GraphicsPath表示,它也是图形基类GraphicsBase 的派生类。关于GraphicsPath,以后再学习。

GDI+ 和GDI的更多相关文章

  1. Win32中GDI+应用(五)--GDI与GDI+编程模型的区别

    在GDI里面,你要想开始自己的绘图工作,必须先获取一个device context handle,然后把这个handle作为绘图复方法的一个参数,才能完成任务.同时,device context ha ...

  2. GDI+ 填充背景时,非常多时候不起作用,GDI、GDI+配合运用

    在ONDRAW中运行GDI+ 填充背景时,不起作用,不知道什么原因 [cpp] view plaincopy Graphics graphics(pDC->GetSafeHdc()); Bitm ...

  3. GDI与GDI+性能比较

    编写程序对GDI和GDI+绘制进行了比较,经过比较,GDI相对GDI+还是有一些性能优势的. 同时比较了每次绘制创建TGPGraphics对象和共用一个TGPGraphics对象的情况,两者性能相差不 ...

  4. GDI与GDI+ 贴图性能对比

    在做绘图相关工作,由于对显示绘制结果实时性有要求,筛选了GDI , 与GDI+ 贴图性能. 这里假设在内存中已绘制完成一张图片,现需求显示在控件上,同时,总是更新全部区域. GDI+ 实现 priva ...

  5. VC++中GDI和GDI+ 的坐标系统介绍

    在Windows应用程序中,只要进行绘图,就要使用GDI坐标系统.Windows提供了几种映射方式,每一种映射都对应着一种坐标系.例如,绘制图形时,必须给出图形各个点在客户区的位置,其位置用x 和y两 ...

  6. gdi和gdi+比较

    http://www.360doc.com/content/10/1013/17/1066008_60709410.shtmlhttp://www.360doc.com/content/10/1013 ...

  7. 超全面的.NET GDI+图形图像编程教程

    本篇主题内容是.NET GDI+图形图像编程系列的教程,不要被这个滚动条吓到,为了查找方便,我没有分开写,上面加了目录了,而且很多都是源码和图片~ (*^_^*) 本人也为了学习深刻,另一方面也是为了 ...

  8. 【VC++技术杂谈007】使用GDI+进行图片格式转换

    本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...

  9. MFC GDI绘图基础

    一.关于GDI的基本概念 什么是GDI? Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Wind ...

随机推荐

  1. repo sync出现“fatal: '../platform/abi/cpp.git' does not appear to be a git repository”的解决方案

    在我下载Android源代码时,在最后一步调用repo sync,出现“fatal: '../platform/abi/cpp.git' does not appear to be a git rep ...

  2. (实用)Linux下安装JDK和Eclipse

    安装Eclipse时前需要确保系统中已经具备Java运行环境,本文以干净系统初次安装Eclipse为例,同时安装JDK和Eclipse. 1.下载JDK压缩包: http://www.oracle.c ...

  3. PHP获取MySql新增记录ID值的3种方法

    From: http://www.jb51.net/article/51473.htm 这篇文章主要介绍了PHP获取MySql新增记录ID值的3种方法,一般使用PHP自带函数mysql_insert_ ...

  4. Blender下各种坐标系

    转载:https://jingyan.baidu.com/article/ed2a5d1f8f018309f7be1779.html 打开blender创建一个立方体.   切换到“自身”坐标系,旋转 ...

  5. Java初学者必学的JSTL

    所谓JSTL就是标签库  JSP Standard Tag Library,如果做为java初学者你看不懂那些$符号的话,就有必要来了解一下JSTL,如果你看到满眼的<%}%>(Scrip ...

  6. Android Material Design控件学习(二)——NavigationView的学习和使用

    前言 上次我们学习了TabLayout的用法,今天我们继续学习MaterialDesign(简称MD)控件--NavigationView. 正如其名,NavigationView,导航View.一般 ...

  7. vue如何加搜狗联盟广告

    搜狗联盟广告和百度联盟广告大同小异,但是好在百度联盟广告的使用方法网上还是可以找到一些,而搜狗联盟广告的教程网上几乎找不到,都是最基本的创建代码位的教程. 在vue中如果要加入搜狗联盟广告,就不能直接 ...

  8. 纯CSS制作的TAB选项卡

    代码 这里主要使用表单的单选按钮来实现这个TAB显示和隐藏,首页tab里的内容默认隐藏,如果单选按钮为选中状态(checked)就显示内容.具体请看下面代码. 关于兼容性,因为是用CSS3来制作的,所 ...

  9. 使用jquery操作session

    摘要: 今天分享的是使用jquery来处理session.我们将使用sessionStorage对象,它类似与localStorage对象,只是sessionStorage是用来储存session数据 ...

  10. [原] unity3d动态加载脚本

    本文记录如何通过unity3d进行脚本资源打包加载 1.创建TestDll.cs文件 public class TestDll : MonoBehaviour {    void Start () { ...