使用GDI+.doc_第1页
使用GDI+.doc_第2页
使用GDI+.doc_第3页
使用GDI+.doc_第4页
使用GDI+.doc_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

l 使用GDI+编程1.引言GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C+类实现的应用程序编程接口。顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易.2.GDI+新增功能(1)渐变的画刷(Gradient Brushes)GDI+允许用户创建一个沿路径或直线渐变的画刷,来填充外形(shapes),路径(paths),区域(regions),渐变画刷同样也可以画直线、曲线、路径,当你用一个线形画刷填充一个外形(shapes)时,颜色就能够沿外形逐渐变化。(2)基数样条函数(Cardinal Splines)GDI支持基数样条函数,而GDI不支持。基数样条是一组单个曲线按照一定的顺序连接而成的一条较大曲线。样条由一系列点指定,并通过每一个指定的点。由于基数样条平滑地穿过组中的每一个点(不出现尖角),因而它比用直线连接创建的路径更精确。下面是分别使用两种方法创建的图形,一个使用基数样条,一个使用直线。(3)持久路径对象Persistent Path Objects在GDI中,路径属于设备描述表(DC),画完后路径就会被破坏。在GDI+中,绘图工作由Graphics对象来完成,你可以创建几个与Graphics分开的路径对象,绘图操作时路径对象不被破环,这样你就可以多次使用同一个路径对象画路径了。(4)变形和矩阵对象Transformations Matrix ObjectGDI+提供了矩阵对象,一个非常强大的工具,使得编写图形的旋转、平移、缩放代码变得非常容易。一个矩阵对象总是和一个图形变换对相联系起来,比方说,路径对象(PATH)有一个Transform方法,它的一个参数能够接受矩阵对象的地址,每次路径绘制时,它能够根据变换矩阵绘制。下面的图形是一个图形变换前后的例子,变换按照先缩放后旋转完成。(5)可伸缩区域 Scalable RegionsGDI+ 在区域(regions)方面对GDI进行了改进,在GDI中,Regions存储在设备坐标中,对Regions 唯一可进行图形变换的操作就是对区域进行平移。而GDI+用世界坐标存储区域(Regions),允许对区域进行任何图形变换(譬如如图所示的缩放),图形变换以变换矩阵存储,下面例子是一个区域变换前后的例子(缩放、旋转、平移)(6)Alpha Blending(混合)你可能会注意到上面显示的图形,红色未平移区域与变换后区域有一部分交叉区域,这一部分形成的梦幻效果就是由GDI+支持的Alpha Blending(混合)实现的,利用alpha融合,你可以指定填充颜色的透明度,透明颜色与背景色相互融合,填充色越透明,背景色显示越清晰,下图所示的四个椭圆被填充了同样的颜色,但由于拥有不同的透明度而呈现不同的显示效果。(7)多种图像格式支持.图像在图形界面程序中占有举足轻重的地位,GDI除了支持BMP等GDI支持的图形格式外,还支持JPEG(Joint Photographic Experts Group)、GIF(Graphics Interchange Format)、PNG(Exchangeable Image File)、EXIF(Portable Network Graphics)、TIFF(Tag Image File Format)等图像格式,你可以直接在程序中使用这些图片文件,而无需考虑它们所用压缩算法。(8)其它。GDI+还将支持其它技术,譬如重新着色、颜色校正、元数据、图形容器,也许这些功能我们会在将来的WindowsXP或者Microsoft VisualStudio。Net中看到.3.编程模式的改变 Device Contexts(设备描述表), Handles(句柄), 和 Graphics Objects(图形对象)如果你曾经使用过GDI编写过应用程序,你肯定对设备描述表(DC)的概念非常熟悉,设备描述表是Windows使用的一个数据结构,用于存储具体设备能力和与如何在设备上重绘一些项目的有关属性信息。而且视频设备的设备描述表还与特定的窗口有关。首先你必须获得一个设备描述表句柄,然后在图形绘制时,你把这个句柄作为一个参数传递给GDI图形绘制函数。当然你也可以把它传递给获得或设置设备描述表有关属性的函数。利用GDI+函数,你不必使用句柄或者设备描述表。相反,你可以简单地创建一个图形对象(Graphics),然后以你熟悉的面向对象的编程方式调用它的方法即可,譬如myGraphicsObject.DrawLine(parameters)。Graphics对象是GDI+的核心,正如设备描述表是GDI的核心一样,设备描述表(DC)和图形对象(Graphics)在不同的环境下扮演着同样的角色,发挥着类似的作用,但是两者也存在着这质的不同。前者使用基于句柄的编程方法而后者使用面向对象的编程方法。图形对象和设备对象一样,与屏幕的显示窗口有关,它包含着与项目重绘有关的属性信息(譬如平滑度),然而图形对象并没有像GDI那样与Pen(画笔)、Path(路径)、Image(图像)、Font(字体)等搅在一起。在GDI中,所有与绘图有关的绘图对象必须选入指定设备描述表中(使用SelectObject函数),才能被指定的设备描述表所使用。而在GDI+中,你只需把这些绘图对象作为一个参数传递给图形对象Graphics方法调用即可,每一个图形对象所使用的绘图工具至于它调用方法使用的参数有关,它可以通过参数使用多种Pen和Brush绘图,而不是与特定的笔和画刷联系在一起。下面的代码分别用两种方法实现红线的绘制,其中线宽3,起点(20,10),终点(200,100)GDIHDC hdc;PAINTSTRUCT ps;HPEN hPen;hdc = BeginPaint(hWnd, &ps); 获得设备句柄,开始绘制hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0);创建红色画笔,宽3SelectObject(hdc, hPen); 选入设备描述表MoveToEx(hdc, 20, 10, NULL); 画线LineTo(hdc, 200, 100);EndPaint(hWnd, &ps); 结束绘制GDI+HDC hdc;PAINTSTRUCT ps;Pen* myPen;Graphics* myGraphics;hdc = BeginPaint(hWnd, &ps);myPen = new Pen(0xffff0000, 3); 创建一个笔,宽3,红色myGraphics = new Graphics(hdc); 利用设备句柄创建图形对象myGraphics-DrawLine(myPen, 20, 10, 200, 100);调用图形对象画线的方法EndPaint(hWnd, &ps);四 如何使用GDI+GDI+并不是Windows XP的专利,它同样可以在其它Windows操作系统下使用(不包括Win3.X),包括64位的Windows版本,按照微软官方的话说,GDI+支持所有基于Windows的应用程序。你只要把GDIPlus.dll拷入Windows的系统目录,即可使用需要GDI+支持的应用程序。Microsoft Visual C全面支持GDI+,Microsoft Visual C+.net使用GDI+有两种方法,一种方法是通过托管(managed )的应用程序实现,另一种方法是在非托管项目中借助于调用C+面向对象类实现。下面是一个基于Win32 SDK的窗口程序。使用要包含GDIplus.h头文件,连接设置要包含GdiPlus.lib库文件。#define UNICODE#include#includeusing namespace Gdiplus;void OnPaint(HWND hWnd)HDC hdc;PAINTSTRUCT ps;hdc = BeginPaint(hWnd, &ps);Graphics graphics(hdc);Pen pen(Color(255, 0, 0, 255);graphics.DrawLine(&pen, 0, 0, 200, 100);EndPaint(hWnd, &ps); / OnPaintLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE,PSTR szCmdLine, int iCmdShow)HWND hWnd;MSG msg;WNDCLASS wndClass;GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken;/ GDI+ 初始化GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);wndClass.style = CS_HREDRAW | CS_VREDRAW;wndClass.lpfnWndProc = WndProc;wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.hInstance = hInstance;wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wndClass.lpszMenuName = NULL;wndClass.lpszClassName = TEXT(GettingStarted);RegisterClass(&wndClass);hWnd = CreateWindow(TEXT(GettingStarted), / window class nameTEXT(Getting Started), / window captionWS_OVERLAPPEDWINDOW, / window styleCW_USEDEFAULT, / initial x positionCW_USEDEFAULT, / initial y positionCW_USEDEFAULT, / initial x sizeCW_USEDEFAULT, / initial y sizeNULL, / parent window handleNULL, / window menu handlehInstance, / program instance handleNULL); / creation parametersShowWindow(hWnd, iCmdShow);UpdateWindow(hWnd);while(GetMessage(&msg, NULL, 0, 0)TranslateMessage(&msg);DispatchMessage(&msg);GdiplusShutdown(gdiplusToken); 关闭GDI+return msg.wParam; / WinMainLRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)switch(message)case WM_PAINT:OnPaint(hWnd);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;default:return DefWindowProc(hWnd, message, wParam, lParam); / WndProc综上所述,我们可以看出使用GDI+进行图形编程更容易,功能更强大,GDI+不仅是Microsoft Visual S的组成部分,也是WindowXP的重要组成部分,未来是GDI的天下,GDI将逐渐退出历史舞台,这是大势所趋,不可逆转。早日锁定GDI+是你明智的选择。l GDI+编程基础(一)GDI+ Vs GDI作者:李昊下载源代码一、GDIGDI是位于应用程序与不同硬件之间的中间层,这种结构让程序员从直接处理不同硬件的工作中解放出来,把硬件间的差异交给了GDI处理。GDI通过将应用程序与不同输出设备特性相隔离,使Windows应用程序能够毫无障碍地在Windows支持的任何图形输出设备上运行。例如,我们可以在不改变程序的前提下,让能在Epson点式打印机上工作的程序也能在激光打印机上工作。它把windows系统中的图形输出转换成硬件命令然后发送给硬件设备。GDI是以文件的形式存储在系统中,系统需要输出图形时把它载入内存,如果转换成硬件命令时遇到非GDI命令,系统还可能载入硬件驱动程序,驱动程序辅助GDI把图形命令转换成硬件命令。二、设备环境Windows系统是用来给应用程序提供设备独立性的工具,它是windows系统为了处理输出设备而使用的一种内部数据结构,设备环境是windos程序,驱动程序,和输出设备(如打印机,绘图仪)之间的纽带,GDI是一组C+类,它在驱动程序的协助下把数据描绘在硬件上,它位于应用程序与硬件之间,把数据从一方传到另一方。在Visual Studio .NET中Micro$oft解决了GDI中的许多问题,并让它变得易用,GDI的.net版本叫做GDI+。三、GDI+GDI+是GDI的下一个版本,它进行了很好的改进,并且易用性更好。GDI的一个好处就是你不必知道任何关于数据怎样在设备上渲染的细节,GDI+更好的实现了这个优点,也就是说,GDI是一个中低层API,你还可能要知道设备,而GDI+是一个高层的API,你不必知道设备。例如你如果要设置某个控件的前景和背景色,只需设置BackColor和ForeColor属性。四、编程模式的变化“GDI uses a stateful model, whereas GDI+ uses a stateless”GDI是有状态的,GDI+是无无状态的。1、不再使用设备环境或句柄在使用GDI绘图时,必须要指定一个设备环境(DC),用来将某个窗口或设备与设备环境类的句柄指针关联起来,所有的绘图操作都与该句柄有关。而GDI+不再使用这个设备环境或句柄,取而代之是使用Graphics对象。与设备环境相类似,Graphics对象也是将屏幕的某一个窗口与之相关联,并包含绘图操作所需要的相关属性。但是,只有这个Graphics对象与设备环境句柄还存在着联系,其余的如Pen、Brush、Image和Font等对象均不再使用设备环境。2、Pen、Brush,Font,Image等对象是图形对象独立的画笔对象能与用于提供绘制方法的图形对象分开创建于维护,Graphics绘图方法直接将Pen对象作为自己的参数,从而避免了在GDI使用SelectObject进行繁琐的切换,类似的还有Brush、Path、Image和Font等。3、“当前位置”GDI绘图操作(如画线)中总存在一个被称为当前位置的特殊位置。每次画线都是以此当前位置为起始点,画线操作结束之后,直线的结束点位置又成为了当前位置。设置当前位置的理由是为了提高画线操作的效率,因为在一些场合下,总是一条直线连着另一条直线,首尾相接。有了当前位置的自动更新,就可避免每次画线时都要给出两点的坐标。尽管有其必要性,但是单独绘制一条直线的场合总是比较多的,因此GDI+取消这个当前位置以避免当无法确定当前位置时所造成的绘图的差错,取而代之的是直接在DrawLine中指定直线起止点的坐标。4、绘制和填充GDI总是让形状轮廓绘制和填充使用同一个绘图函数,例如Rectangle。轮廓绘制需要一个画笔,而填充一个区域需要一个画刷。也就是说,不管我们是否需要填充所绘制的形状,我们都需要指定一个画刷,否则GDI采用默认的画刷进行填充。这种方式确实给我们带来了许多不便,现在GDI+将形状轮廓绘制和填充操作分开而采用不同的方法,例如DrawRectangle和FillRectangle分别用来绘制和填充一个矩形。5、区域的操作GDI提供了许多区域创建函数,如:CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn和CreatePolyPolygonRgn等。诚然,这些函数给我们带来了许多方便。但在GDI+中,由于为了便于将区域引入矩阵变换操作,GDI+简化一般区域创建的方法,而将更复杂的区域创建交由Path接管。由于Path对象是与设备环境分离开来的,因而可以直接在Region构造函数中加以指定。五、GDI+新特色GDI+与GDI相比,增加了下列新的特性:1、渐变画刷以往GDI实现颜色渐变区域的方法是通过使用不同颜色的线条来填充一个裁剪区域而达到的。现在GDI+拓展了GDI功能,提供线型渐变和路径渐变画刷来填充一个图形、路径和区域,甚至也可用来绘制直线、曲线等。这里的路径可以视为由各种绘图函数产生的轨迹。2、样条曲线对于曲线而言,最具实际意义的莫过于样条曲线。样条曲线是在生产实践的基础上产生和发展起来的。模线间的设计人员在绘制模线时,先按给定的数据将型值点准确地点到图板上。然后,采用一种称为样条的工具(一根富有弹性的有机玻璃条或木条),用压铁强迫它通过这些型值点,再适当调整这些压铁,让样条的形态发生变化,直至取得合适的形状,才沿着样条画出所需的曲线。如果我们把样条看成弹性细梁,那么压铁就可看成作用在这梁上的某些点上的集中力。GDI+的Graphics: DrawCurve函数中就有一个这样的参数用来调整集中力的大小。除了样条曲线外,GDI+还支持原来GDI中的Bezier曲线。3、独立的路径对象在GDI中,路径是隶属于一个设备环境(上下文),也就是说一旦设备环境指针超过它的有效期,路径也会被删除。而GDI+是使用Graphics对象来进行绘图操作,并将路径操作从Graphics对象分离出来,提供一个GraphicsPath类供用户使用。这就是说,我们不必担心路径对象会受到Graphics对象操作的影响,从而可以使用同一个路径对象进行多次的路径绘制操作。4、矩阵和矩阵变换在图形处理过程中常需要对其几何信息进行变换以便产生复杂的新图形,矩阵是这种图形几何变换最常用的方法。为了满足人们对图形变换的需求,GDI+提供了功能强大的Matrix类来实现矩阵的旋转、错切、平移、比例等变换操作,并且GDI+还支持Graphics图形和区域(Region)的矩阵变换。5、Alpha通道合成运算在图像处理中,Alpha用来衡量一个像素或图像的透明度。在非压缩的32位RGB图像中,每个像素是由四个部分组成:一个Alpha通道和三个颜色分量(R、G和B)。当Alpha值为0时,该像素是完全透明的,而当Alpha值为255时,则该像素是完全不透明。Alpha混色是将源像素和背景像素的颜色进行混合,最终显示的颜色取决于其RGB颜色分量和Alpha值。它们之间的关系可用下列公式来表示显示颜色 = 源像素颜色 X alpha / 255 + 背景颜色 X (255 - alpha) / 255GDI+的Color类定义了ARGB颜色数据类型,从而可以通过调整Alpha值来改变线条、图像等与背景色混合后的实际效果。6、多图片格式的支持GDI+提供了对各种图片的打开,存储功能。通过GDI+,我们能够直接将一幅BMP文件存储成JPG或其它格式的图片文件。除了上述新特性外,GDI+还将支持重新着色、色彩修正、消除走样、元数据以及Graphics容器等特性。六、VC.net中使用GDI+的方法在Visual C+.NET使用GDI+一般遵循下列步骤:(1)、在应用程序中添加GDI+的包含文件gdiplus.h以及附加的类库gdiplus.lib。通常gdiplus.h包含文件添加在应用程序的stdafx.h文件中,而gdiplus.lib可用两种进行添加:第一种是直接在stdafx.h文件中添加下列语句:#pragma comment( lib, gdiplus.lib )另一种方法是:选择项目-属性菜单命令,在弹出的对话框中选中左侧的链接器-输入选项,在右侧的附加依赖项框中键入gdiplus.lib,(2)、在应用程序项目的应用类中,添加一个成员变量,如下列代码:ULONG_PTR m_gdiplusToken;其中,ULONG_PTR是一个DWORD数据类型,该成员变量用来保存GDI+被初始化后在应用程序中的GDI+标识,以便能在应用程序退出后,引用该标识来调用Gdiplus: GdiplusShutdown来关闭GDI+。(3)、在应用类中添加ExitInstance的重载,并添加下列代码用来关闭GDI+:int CGDIPlusApp:ExitInstance()Gdiplus:GdiplusShutdown(m_gdiplusToken);return CWinApp:ExitInstance();(4)、在应用类的InitInstance函数中添加GDI+的初始化代码:BOOL CGDIPlusApp:InitInstance()CWinApp:InitInstance();Gdiplus:GdiplusStartupInput gdiplusStartupInput;Gdiplus:GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);.(5)、在需要绘图的窗口或视图类中添加GDI+的绘制代码:void CGDIPlusView:onDraw(CDC *pDC)Graphics graphics( pDC-m_hDC );GraphicsPath path; / 构造一个路径path.AddEllipse(50, 50, 200, 100);/ 使用路径构造一个画刷PathGradientBrush pthGrBrush(&path);/ 将路径中心颜色设为蓝色pthGrBrush.SetCenterColor(Color(255, 0, 0, 255);/ 设置路径周围的颜色为蓝芭,但alpha值为0Color colors = Color(0, 0, 0, 255);INT count = 1;pthGrBrush.SetSurroundColors(colors, &count);graphics.FillRectangle(&pthGrBrush, 50, 50, 200, 100);LinearGradientBrush linGrBrush(Point(300, 50),Point(500, 150),Color(255, 255, 0, 0), / 红色Color(255, 0, 0, 255); / 蓝色graphics.FillRectangle(&linGrBrush, 300, 50, 200, 100);l GDI+编程(二)使用画笔作者:李昊画笔常用于绘制图形的轮廓.GDI+的画笔除了具有常见的色彩和宽度属性外,还具有对齐方式,线帽,变换方式等属性。GDI+中通过Pen类来定义画笔对象。(一)、构造与使用画笔Pen(brush, width); /用颜色与线宽构造一个画笔Pen(color, width); /用画刷与宽度构造一个画笔例子:Pen pen(Color(255, 0, 0, 0),1);/用第一个构造函数.构造宽度为1的黑色画刷graphics.DrawLine(&pen, 20, 10, 300, 100);Image image(LTexture1.jpg);TextureBrush tBrush(&image);graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight();Pen texturedPen(&tBrush, 30);/用第二个构造函数,用一个纹理画刷graphics.DrawEllipse(&texturedPen, 100, 20, 200, 100);(二)、设值宽度与对齐方式创建画笔时,可以把宽度当作参数传给构造函数,我们也可以使用SetWidth()方法来改变画笔的线宽。一个理想的线宽度为0, 我们绘制一条直线时,像素位于直线的正中,下面的例子中我们用宽度为1的先用黑画笔绘制一条直线,在用绿色的宽度为10的画笔再绘制一次。Pen blackPen(Color(255, 0, 0, 0), 1);Pen greenPen(Color(255, 0, 255, 0), 10);greenPen.SetAlignment(PenAlignmentCenter);graphics.DrawLine(&greenPen, 10, 100, 100, 50);graphics.DrawLine(&blackPen, 10, 100, 100, 50);我们把绿色画笔设为中对齐时:graphics.DrawRectangle(&greenPen, 10, 100, 50, 50);graphics.DrawRectangle(&blackPen, 10, 100, 50, 50);我们把绿色画笔设为内对齐时:greenPen.SetAlignment(PenAlignmentInset);这样我们可以按需要来设置对齐方式。(三)、设置笔帽我们可以用多种方式来绘制线条的头部与尾部形状,GDI+支持圆形,方形,菱形,与箭头等样式的笔帽。Pen pen(Color(255, 0, 0, 255), 8);pen.SetStartCap(LineCapArrowAnchor);pen.SetEndCap(LineCapRoundAnchor);graphics.DrawLine(&pen, 20, 175, 300, 175);效果如下:(四)、设置两条直线的连接形GDI+为我们提供了当两条直线连接时连接处形状的设置,有四种方式:斜接(miter)、斜切(bevel),圆形(round),剪裁斜接(miter clipped)。GraphicsPath path;Pen penJoin(Color(255, 0, 0, 255), 8);path.StartFigure();path.AddLine(Point(50, 200), Point(100, 200);path.AddLine(Point(100, 200), Point(100, 250);penJoin.SetLineJoin(LineJoinBevel);graphics.DrawPath(&penJoin, &path);(五)、自定义线型GDI+为我们提供了好多线型,如果满足不了我们的需求,我们可以用成员函数SetDashPattern可以使用一个预定义的数组来描述画笔的虚实, 下面的例子用自定义风格绘制了一条直线,所用数组为5, 2, 15, 4,如果你用画笔宽度去乘数组得25, 10, 75, 20,显示的曲线在25与75间变换, 空白在10与20间变换。REAL dashValues4 = 5, 2, 15, 4;Pen blackPen(Color(255, 0, 0, 0), 5);blackPen.SetDashPattern(dashValues, 4);graphics.DrawLine(&blackPen, Point(5, 5), Point(405, 5);有一点要明白,最后的那条虚线要比25单位少,这样它才能在405处结束。(六)、画笔的旋转变换我们可以在程序中修改画笔在水平与垂直方向上的宽度的,假设我们有一个画笔的宽度为5,那么我们用它来绘制的矩形在四条边上长度都是一样的, 如果想让在水平与数值方向上不一致,我们可以使用变换,有三种方式可以实现上面的要求:Pen pen(Color(255,0,0,255);pen.SetWidth(5);Matrix matrix(1,0,0,2,0,0);pen.MutiplyTransform(&matrix,MatrixOrderPrepend);/方法一pen.SetTransform(&matrix);/方法二pen.ScaleTransform(1,4);graphics.DrawRectange(&pen,50,50,200,200);还可以对画笔进行旋转变换,旋转是相对在水平宽度与垂直位置上不一致的画笔而言的左图为缩放变换,右图为旋转变换。l 在VC6.0时边要加入以下三句到stdafx.h里边#defineULONG_PTRULONG#includeusingnamespaceGdiplus;#pragmacomment(lib,gdiplus.lib)l 作为新一代操作系统的图形处理内核,GDI+在Windows XP和Windows Server 2003操作系统中扮演着极其重要的角色。 GDI+的出现 ,是对传统程序员的一种解脱。本书是目前国内少有的全面介绍GDI+编程的参考书。本书从画笔与画刷、文本与字体、区域与路径等基础知识谈起,将GDI+的技术细节一一展示。此外,GDI+的矩阵运算、图像的编码与解码、图像色彩信息校正等深层次知识,也都能够在本书中找到详细的说明。为了让读者更快地掌握GDI+编程,在每一章的内容中,都配有详尽的程序源代码,以强化具体的理论阐述。本书是作者长期从事GDI+编程的经验总结,所提供的源代码具有一定的代表性。 本书适合于能够熟练使用C+语言进行程序开发的中、高级程序设计人员阅读使用。另外,不论读者对GDI或GDI+编程熟悉与否,都可通过阅读本书全面掌握GDI+编程的每一个技术细节。同时,对于使用其他语言如C#、VB、Delphi等进行程序开发的读者,也可以通过本书对GDI+的基本原理及高级应用有一个全面的认识。 l 在Windows Mobile上使用GDI+GDI+是Windows操作系统中提供二维矢量图形、图像处理和版式的部分。GDI+在GDI(较早版本的Windows中提供的Graphics Device Interface)的基础上进行了改进,添加了新功能并优化了现有功能。.NET Framework已经实现了托管的GDI+编程接口,而.NET Compact Framework并没有支持GDI+。这使得Windows Mobile应用程序在实现一些漂亮的绘图效果时(如:渐变),没有桌面应用程序那么容易。Windows Mobile提供了Game API和Direct3D Mobile,但这两套API是针对游戏程序的,并不一定适合普通的应用程序。事实上从Windows Mobile 5.0开始就支持GDI+了,开发人员可以利用C语言或者P/Invoke来使用这些API。OpenNETCF顾问Alex Feinman已经将Windows Mobile的GDI+ API用C#语言封装好了,并且提供了一些很漂亮的示例程序。BrushesPens Demo application被过滤广告文章信息作者:ADDING时间:2004-02-20出处:yesky责任编辑:方舟文章导读Visual C+.NET GDI+编程基础GDI+提供从简单到复杂图形绘制的大量方法,可以通过对路径和区域的操作构造出复杂的图形GDI+提供从简单到复杂图形绘制的大量方法,并且我们可以通过对路径和区域的操作构造出更复杂的图形,这在CAD等场合极为有用。当然,在绘图之前我们有必要搞清一些基本内容,如坐标空间、画笔和画刷等。坐标空间及其变换在视图和窗口中绘图或定位总是在一个二维坐标系进行,依据作用方法的不同,坐标有多种表示方法,并且各种不同坐标之间可以相互转换。1 世界坐标系、设备坐标系和页面坐标系GDI+为我们提供了三种坐标空间:世界坐标系、页面坐标系和设备坐标系。世界坐标系是应用程序用来进行图形输入输出所使用的一种与设备无关的笛卡尔坐标系。通常,我们可以根据自己的需要和方便定义一个自己的世界坐标系,这个坐标系称为用户坐标系。例如,前面DrawLine(&newPen, 20, 10, 200, 100);中的坐标都是以这个用户坐标系为基准的,默认时使用像素为单位。设备坐标系是指显示设备或打印设备坐标系下的坐标,它的特点是以设备上的象素点为单位。对于窗口中的视图而言,设备坐标的原点在客户区的左上角,x坐标从左向右递增,y坐标自上而下递增。由于设备的分辨率不同,相同坐标值的物理位置可能不同。如对于边长为100的正方形,当显示器为640 x 480和800 x 600时的大小是不一样的。页面坐标系是指某种映射模式下的一种坐标系。所谓映射是指将世界坐标系通过某种方式进行的变换。默认时,设备坐标和页面坐标是一致的。2 坐标映射和坐标原点的设置为了能保证打印或显示的结果不受设备的影响,GDI+定义了一些映射方法和属性来决定设备坐标和页面坐标之间的关系。这些映射方法和属性有: SetPageUnit和GetPageUnit 这两个属性函数是用来设置和获取每个单位所对应的实际度量单位。它通常可以有下列的值:UnitDisplay - 每个页面单位为1/75英寸;UnitPixel - 每个页面单位为1个像素,此时页面坐标与设备坐标相同;UnitPoint - 每个页面单位为1/72英寸;UnitInch - 每个页面单位为1英寸;UnitDocument - 每个页面单位为1/300英寸;UnitMillimeter- 每个页面单位为1毫米。例如,或将Ex_GDIPlusDlg示例中的绘图代码修改成:CPaintDC dc(this); using namespace Gdiplus;Graphics graphics( dc.m_hDC );graphics.SetPageUnit(UnitMillimeter);Pen newPen( Color( 255, 0, 0 ), 3 );HatchBrush newBrush( HatchStyleCross,Color(255, 0, 255, 0),Color(255, 0, 0, 255); graphics.DrawRectangle( &newPen, 50, 50, 100, 60); graphics.FillRectangle( &newBrush, 50, 50, 100, 60);则笔画宽度为3,以及矩形的左上角顶点坐标和大小单位都为毫米,其结果如图所示。SetPageScale和GetPageScaleGDI+的这两个属性函数分别用来设置和获取页面的缩放比例。例如,当上面的绘图代码变成:.graphics.SetPageUnit(UnitMillimeter);graphics.SetPageScale( (REAL)0.1);Pen newPen( Color( 255, 0, 0 ), 3 );.代码中,REAL是一个浮点类型的定义。上述代码的结果如图2所示。图2TranslateTransformGDI+的TranslateTransform方法用来改变坐标的原点位置,例如TranslateTransform(100, 50)是将坐标原点移到点(100,50)。画笔画笔是用来绘制各种直线和曲线的一种图形工具,GDI+的Pen类为画笔提供了丰富的方法。一般来说,我们可以通过其构造函数来指定画笔的颜色和宽度,其定义如下:Pen( const Color& color, REAL width );其中,color是用来指定画笔颜色,width用来指定画笔宽度。REAL是一个float类型定义,而Color是GDI+的一个颜色类,它既可以指定一个ARGB颜色类型,也可以使用GDI+预定义的颜色值,甚至可以将COLORREF转换成Color类型的颜色。例如,下面的代码都是创建一个宽度为3,颜色为蓝色的画笔:Pen newPen( Color( 255, 0, 0, 255 ), 3 );Pen newPen(Color( 0, 0, 255), 3);/ 当Color只有三个实参时,颜色Alpha分量值为255。Pen newPen(Color:Blue, 3);COLORREF crRef = RGB( 0, 0, 255);Color color;color.SetFromCOLORREF(crRef);Pen newPen(color, 3);除了颜色外,GDI+的Pen类还提供SetDashStyle和SetDashPattern方法来设置画笔的预定义风格和自定义类型。其中,预定义风格可以有:DashStyleSolid(实线)、DashStyleDash(虚线)、DashStyleDot(点线)、DashStyleDashDot(点划线)、DashStyleDashDotDot(双点划线)和DashStyleCustom(自定义类型)。例如下列代码,其结果如图7.6所示:using namespace Gdiplus;Graphics graphics( pDC-m_hDC );Pen pen(Color(255, 0, 0, 255), 15);pen.SetDashStyle(DashStyleDash);graphics.DrawLine(&pen, 0, 50, 400, 150);pen.SetDashStyle(DashStyleDot);graphics.DrawLine(&pen, 0, 80, 400, 180); pen.SetDashStyle(DashStyleDashDot);graphics.DrawLine(&pen, 0, 110, 400, 210); 但是,在工程应用中,预定义风格的画笔有时并不能满足实际的需求,而必须自己定义一些线型,这需要通过SetDashPattern函数来实现。SetDashPattern的原型如下:Status SetDashPattern( const REAL* dashArray, INT count);其中,dashArray是一个包含短划和间隔长度的数组,count表示数组的大小。注意,dashArray中的短划长度和间隔长度是成对出现的,例如下列代码是使用自定义类型的画笔,其结果如图7.7所示。REAL dashVals4 = 2, / 短划长为22, / 间隔为215, / 短划长为152; / 间隔为2Pen pen(Color(255, 0, 0, 0), 5);pen.SetDashPattern(dashVals, 4);graphics.DrawLine(&pen, 5, 20, 405, 200); 需要说明的是,GDI+的Pen类还提供SetStartCap和SetEndCap方法来设置一条直线的起始端和终止端的样式。例如下面的代码,其结果如图7.8所示。using namespace Gdiplus;Graphics graphics( pDC-m_hDC );Pen pen( Color( 255, 0, 0, 255 ), 15); pen.SetStartCap(LineCapFlat);pen.SetEndCap(LineCapSquare);graphics.DrawLine(&pen, 50, 50, 250, 50);pen.SetStartCap(LineCapRound );pen.SetEndCap(LineCapRoundAnchor);graphics.DrawLine(&p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论