1、 教学提示:本章主要介绍图形图像编程的基本概念,如设备环境、教学提示:本章主要介绍图形图像编程的基本概念,如设备环境、坐标系统,介绍了图形设备接口、绘图工具、绘图函数、位图的应用,坐标系统,介绍了图形设备接口、绘图工具、绘图函数、位图的应用,并结合实例介绍了基于并结合实例介绍了基于.NET框架的框架的GDI+编程方法。编程方法。教学目标:通过本章的学习,掌握图形图像编程的基本概念,熟教学目标:通过本章的学习,掌握图形图像编程的基本概念,熟悉绘图工具、绘图函数的应用以及基于悉绘图工具、绘图函数的应用以及基于.NET框架的框架的GDI+编程方法。编程方法。支持图形是支持图形是Windows编程的一
2、个核心部分,因为在编程的一个核心部分,因为在Windows当中,当中,每一个屏幕输出,无论是文本、图像或图片,都是作为图形绘制到屏幕每一个屏幕输出,无论是文本、图像或图片,都是作为图形绘制到屏幕上的。上的。Windows提供了图形设备接口提供了图形设备接口(Graphical Device Interface,简称,简称GDI)来实现绘制图形的功能。来实现绘制图形的功能。GDI提供了一组预定义的提供了一组预定义的GDI对象,如画对象,如画笔、画刷等,让用户可以在任何设备上绘图。实际上,笔、画刷等,让用户可以在任何设备上绘图。实际上,GDI起到了应用起到了应用程序和实际输出设备之间的接口作用,如
3、图程序和实际输出设备之间的接口作用,如图9.1所示。所示。Windows 应用程序 GDI 设备 屏幕 打印机 图9.1 GDI在Windows系统中的作用9.2.1 GDI对象对象9.2.2 使用画笔工具使用画笔工具CPen9.2.3 使用画刷工具使用画刷工具CBrush9.2.4 使用字体工具使用字体工具CFont9.2.5 编写一个简单的绘图程序编写一个简单的绘图程序MyPainter 除了设备环境之外,除了设备环境之外,Windows也提供一套也提供一套GDI对象。不同的绘图工具对象。不同的绘图工具(如画笔和画刷如画笔和画刷)和绘图属性和绘图属性(如颜色和字体如颜色和字体)都叫作都叫作
4、GDI对象。对象。MFC定义了几种定义了几种GDI对象类型,包括画笔、画刷以及字体工具等,具体对象类型,包括画笔、画刷以及字体工具等,具体如下:如下:笔笔 CPen刷子刷子 CBrust字体字体 CFont位图位图 CBitmap调色板调色板 CPalette区域区域 CRgn返回创建一个画笔,仅需提供画笔的线型、宽度和颜色。创建一个画笔,仅需提供画笔的线型、宽度和颜色。返回 对于用画笔画出的封闭图形,画刷可以用特定的颜色或图形来填对于用画笔画出的封闭图形,画刷可以用特定的颜色或图形来填满它。可创建实心和图形画刷,甚至可以包含指定的位图来创建一个满它。可创建实心和图形画刷,甚至可以包含指定的位
5、图来创建一个画刷。画刷。返回 Windows字体的信息是用字体的信息是用LOGFONT结构描述的。结构描述的。LOGFONT结结构使用了构使用了14个字段保存完整的字体信息描述,如表个字段保存完整的字体信息描述,如表9.3所示。所示。返回表9.3 LOGFONT结构包含的字体信息字 段描 述lfHeight字体高度lfWidth字体宽度lfEscapement画文本的角度lfOrientation字体倾斜的角度lfWeight字体的粗细lfItalic是否斜体,非零表示斜体lfUnderline是否有下划线,非零表示有下划线lfStrikeOut是否镂空,非零表示字体镂空lfCharSet字体
6、字符集lfOutPrecision如何匹配字体lfClipPrecision如何剪贴字体lfQuality字体的打印质量lfPitchAndFamily字体间距和字体族lfFaceName字体名称返回 通过上面的学习,我们了解了通过上面的学习,我们了解了GDI绘图工具的基本用法。下面我们绘图工具的基本用法。下面我们来建立一个简单的绘图程序:来建立一个简单的绘图程序:MyPaint,它实现鼠标绘图的功能。要实,它实现鼠标绘图的功能。要实现鼠标绘图,可以这样考虑:鼠标左键按下时开始绘图,记录下当时的现鼠标绘图,可以这样考虑:鼠标左键按下时开始绘图,记录下当时的坐标作为起点;鼠标移动时,每移动到一个
7、新位置就从起点画一条直线坐标作为起点;鼠标移动时,每移动到一个新位置就从起点画一条直线到该新位置,然后把当前位置又作为新的起点;鼠标左键松开时,绘图到该新位置,然后把当前位置又作为新的起点;鼠标左键松开时,绘图结束。结束。返回 Windows用位图用位图(Bitmap)来显示和保存图像,从单色到来显示和保存图像,从单色到24位真彩位真彩色图像都可以储存到位图中。色图像都可以储存到位图中。位图实际上是一个像素值阵列。根据颜色精度的不同,每一个像位图实际上是一个像素值阵列。根据颜色精度的不同,每一个像素可以用素可以用1、4、8或或24个位来表示。黑白位图可以用一位代表一个像个位来表示。黑白位图可以
8、用一位代表一个像素,因为素,因为1位已经能标识两种颜色了;位已经能标识两种颜色了;16色位图用色位图用4位表示一个像素,位表示一个像素,256色的位图每一个字节存储一个像素,而真彩色位图中每个像素用色的位图每一个字节存储一个像素,而真彩色位图中每个像素用3个字节来表示,红、绿、蓝个字节来表示,红、绿、蓝3种颜色分量分别占用一个字节。种颜色分量分别占用一个字节。位图分为设备相关位图位图分为设备相关位图(DDB)和与设备无关的位图和与设备无关的位图(DIB),二者有不,二者有不同的用途。同的用途。9.3.1 设备相关位图设备相关位图 9.3.2 设备无关位图设备无关位图 DDB(Device-De
9、pendent Bitmap)依赖于具体设备,这主要体现在以依赖于具体设备,这主要体现在以下两个方面:下两个方面:DDB的颜色模式必须与输出设备相一致。例如,如果当前的显示设备的颜色模式必须与输出设备相一致。例如,如果当前的显示设备是是256色模式,那么色模式,那么DDB必然也是必然也是256色的,即一个像素用一个字节表示。色的,即一个像素用一个字节表示。在在256色以下的位图中储存的像素值是系统调色板的索引,其颜色依色以下的位图中储存的像素值是系统调色板的索引,其颜色依赖于系统调色板。赖于系统调色板。由于由于DDB高度依赖输出设备,所以高度依赖输出设备,所以DDB只能存在于内存中,它要么在视
10、只能存在于内存中,它要么在视频内存中,要么在系统内存中。而且,频内存中,要么在系统内存中。而且,DDB不能用来长期存储色彩丰富不能用来长期存储色彩丰富的位图,对于那些颜色比较丰富的位图,只有使用节将要介绍的的位图,对于那些颜色比较丰富的位图,只有使用节将要介绍的DIB才才能长期保存。能长期保存。返回1.什么是设备无关位图什么是设备无关位图2.DIB的结构的结构3.自己编写一个自己编写一个DIB类类返回 前面我们说过,位图实际上是一个像素值阵列。如果位图文件中的前面我们说过,位图实际上是一个像素值阵列。如果位图文件中的每个颜色值都包含完整的每个颜色值都包含完整的RGB数值,那么,由于这个颜色值完
11、全在位图数值,那么,由于这个颜色值完全在位图中得到定义,这个文件就是一个设备无关位图。如果每个颜色值实际上中得到定义,这个文件就是一个设备无关位图。如果每个颜色值实际上都是对某个颜色表的字节索引,而且位图同时包含了这个颜色表,那么都是对某个颜色表的字节索引,而且位图同时包含了这个颜色表,那么这个文件仍然是设备无关的。像这样的颜色索引常用于压缩位图的大小,这个文件仍然是设备无关的。像这样的颜色索引常用于压缩位图的大小,一个一个8位索引只占用位索引只占用32位位RGB值的值的1/4。设备无关位图设备无关位图(Device Independent Bitmaps,简称,简称DIB)由对颜色表的索由对
12、颜色表的索引组成,这个颜色表在系统的显卡中被定义。引组成,这个颜色表在系统的显卡中被定义。返回 要想使用要想使用DIB,首先应该先了解,首先应该先了解DIB的结构。在内存中,一个完整的的结构。在内存中,一个完整的DIB由两部分组成:一个由两部分组成:一个BITMAPINFO结构和一个存储像素阵列的数组。结构和一个存储像素阵列的数组。返回 对对DIB的操作比较复杂,我们现在编写一个名为的操作比较复杂,我们现在编写一个名为CDib的较简单的的较简单的DIB类,该类封装了类,该类封装了DIB的基本操作,它的主要成员函数包括:的基本操作,它的主要成员函数包括:BOOL Load(LPCTSTR lps
13、zFileName);BOOL Save(LPCTSTR pszFilename);BOOL SetPalette(CDC*pDC);BOOL Draw(CDC*pDC,int nX=0,int nY=0,int nWidth=-1,int nHeight=-1);返回 Windows用位图用位图(Bitmap)来显示和保存图像,从单色到来显示和保存图像,从单色到24位真彩位真彩色图像都可以储存到位图中。色图像都可以储存到位图中。位图实际上是一个像素值阵列。根据颜色精度的不同,每一个位图实际上是一个像素值阵列。根据颜色精度的不同,每一个像素可以用像素可以用1、4、8或或24个位来表示。黑白位图
14、可以用一位代表一个个位来表示。黑白位图可以用一位代表一个像素,因为像素,因为1位已经能标识两种颜色了;位已经能标识两种颜色了;16色位图用色位图用4位表示一个像素,位表示一个像素,256色的位图每一个字节存储一个像素,而真彩色位图中每个像素用色的位图每一个字节存储一个像素,而真彩色位图中每个像素用3个字节来表示,红、绿、蓝个字节来表示,红、绿、蓝3种颜色分量分别占用一个字节。种颜色分量分别占用一个字节。位图分为设备相关位图位图分为设备相关位图(DDB)和与设备无关的位图和与设备无关的位图(DIB),二者有不,二者有不同的用途。同的用途。9.3.1 设备相关位图设备相关位图 9.3.2 设备无关
15、位图设备无关位图 DDB(Device-Dependent Bitmap)依赖于具体设备,这主要体现在以依赖于具体设备,这主要体现在以下两个方面:下两个方面:DDB的颜色模式必须与输出设备相一致。例如,如果当前的显示设备的颜色模式必须与输出设备相一致。例如,如果当前的显示设备是是256色模式,那么色模式,那么DDB必然也是必然也是256色的,即一个像素用一个字节表示。色的,即一个像素用一个字节表示。在在256色以下的位图中储存的像素值是系统调色板的索引,其颜色依色以下的位图中储存的像素值是系统调色板的索引,其颜色依赖于系统调色板。赖于系统调色板。由于由于DDB高度依赖输出设备,所以高度依赖输出
16、设备,所以DDB只能存在于内存中,它要么在视只能存在于内存中,它要么在视频内存中,要么在系统内存中。而且,频内存中,要么在系统内存中。而且,DDB不能用来长期存储色彩丰富不能用来长期存储色彩丰富的位图,对于那些颜色比较丰富的位图,只有使用节将要介绍的的位图,对于那些颜色比较丰富的位图,只有使用节将要介绍的DIB才才能长期保存。能长期保存。返回1.什么是设备无关位图什么是设备无关位图2.DIB的结构的结构3.自己编写一个自己编写一个DIB类类返回 前面我们说过,位图实际上是一个像素值阵列。如果位图文件中的前面我们说过,位图实际上是一个像素值阵列。如果位图文件中的每个颜色值都包含完整的每个颜色值都
17、包含完整的RGB数值,那么,由于这个颜色值完全在位图数值,那么,由于这个颜色值完全在位图中得到定义,这个文件就是一个设备无关位图。如果每个颜色值实际上中得到定义,这个文件就是一个设备无关位图。如果每个颜色值实际上都是对某个颜色表的字节索引,而且位图同时包含了这个颜色表,那么都是对某个颜色表的字节索引,而且位图同时包含了这个颜色表,那么这个文件仍然是设备无关的。像这样的颜色索引常用于压缩位图的大小,这个文件仍然是设备无关的。像这样的颜色索引常用于压缩位图的大小,一个一个8位索引只占用位索引只占用32位位RGB值的值的1/4。设备无关位图设备无关位图(Device Independent Bitm
18、aps,简称,简称DIB)由对颜色表的索由对颜色表的索引组成,这个颜色表在系统的显卡中被定义。引组成,这个颜色表在系统的显卡中被定义。返回 要想使用要想使用DIB,首先应该先了解,首先应该先了解DIB的结构。在内存中,一个完整的的结构。在内存中,一个完整的DIB由两部分组成:一个由两部分组成:一个BITMAPINFO结构和一个存储像素阵列的数组。结构和一个存储像素阵列的数组。返回 对对DIB的操作比较复杂,我们现在编写一个名为的操作比较复杂,我们现在编写一个名为CDib的较简单的的较简单的DIB类,该类封装了类,该类封装了DIB的基本操作,它的主要成员函数包括:的基本操作,它的主要成员函数包括
19、:BOOL Load(LPCTSTR lpszFileName);BOOL Save(LPCTSTR pszFilename);BOOL SetPalette(CDC*pDC);BOOL Draw(CDC*pDC,int nX=0,int nY=0,int nWidth=-1,int nHeight=-1);返回 GDI+是是GDI的扩展,也是用于的扩展,也是用于Microsoft Windows XP的图形设备的图形设备接口。同接口。同GDI一样,一样,GDI+也用来在屏幕或打印机上显示信息,并可也用来在屏幕或打印机上显示信息,并可以由开发人员用来创建设备无关的应用程序。而且,以由开发人员用
20、来创建设备无关的应用程序。而且,GDI+的功能比的功能比GDI更强大。更强大。GDI+包含在包含在.NET框架当中,可以用来创建功能强大的框架当中,可以用来创建功能强大的图形程序。图形程序。GDI+程序是通过程序是通过C+托管程序实现的。托管程序实现的。9.4.1 GDI+的新功能的新功能9.4.2 GDI+命名空间命名空间9.4.3 GDI+中常用的类中常用的类9.4.4 用用GDI+编写图形程序编写图形程序 GDI+的的API除了比除了比GDI更简单灵活外,还加入了许多新功能,比如:更简单灵活外,还加入了许多新功能,比如:色彩改进。色彩改进。GDI+拥有了更多的颜色,并与其他的颜色,如拥有
21、了更多的颜色,并与其他的颜色,如Windows的的颜色兼容。颜色兼容。独立路径支持。独立路径支持。渐变画刷。渐变画刷。基数样条。基数样条。矩阵对象和区域变换。矩阵对象和区域变换。Alpha混色。混色。返回 命名空间命名空间GDI+在在Drawing命名空间和它的命名空间和它的5个次命名空间里定义。个次命名空间里定义。所有所有Drawing代码存在于代码存在于System.Drawing.DLL程序集里。这些命名空间程序集里。这些命名空间包括:包括:System.Drawing System.Drawing.Design System.Drawing.Printing System.Drawin
22、g.Imaging System.Drawing.Drawing2D System.Drawing.Text返回 与与GDI不同,不同,GDI+不需要传递句柄或设备环境给不需要传递句柄或设备环境给GDI函数。在函数。在GDI+中,我们使用中,我们使用Graphics对象并直接调用其方法实现绘图功能。对象并直接调用其方法实现绘图功能。GDI+使用面向对象的模式,而使用面向对象的模式,而GDI使用基于句柄的编程模式。使用基于句柄的编程模式。Graphics对象是对象是GDI+的基础,就像设备环境是的基础,就像设备环境是GDI的基础一样。的基础一样。另外,有如下另外,有如下4种常见的种常见的GDI+对象,是在对象,是在GDI+编程过程中必不可少的。编程过程中必不可少的。Brush:用来填充各种图形。:用来填充各种图形。Pen:用来画线条,多边形,包括长方形,弧形以及饼状图形。:用来画线条,多边形,包括长方形,弧形以及饼状图形。Font:指定文本的字体。:指定文本的字体。Color:某一具体图形绘制对象的颜色。:某一具体图形绘制对象的颜色。返回9.5.1 完善完善MyPainter绘图程序绘图程序9.5.2 位图显示程序位图显示程序