GDI+

原创 2001年09月28日 12:18:00

 

 

2001年6月,微软新发布GDI+(念GDI plus)。此技术首先被应用于WindowxXP,但在所有的Windows系统中都可以使用,需要gdiplus.dll支持。

GDI+ is the subsystem of the Microsoft Windows XP operating system that is responsible for displaying information on screens and printers. GDI+ is an application programming interface (API) that is exposed through a set of C++ classes.

As its name suggests, GDI+ is the successor to GDI, the graphics device interface included with earlier versions of Windows. Windows XP supports GDI for compatibility with existing applications, but programmers of new applications should use GDI+ for all their graphics needs because GDI+ optimizes many of the capabilities of GDI and also provides additional features.

A graphics device interface, such as GDI+, allows application programmers to display information on a screen or printer without having to be concerned about the details of a particular display device. The application programmer makes calls to methods provided by GDI+ classes and those methods in turn make the appropriate calls to specific device drivers. GDI+ insulates the application from the graphics hardware, and it is this insulation that allows developers to create device-independent applications.

介绍一些新特性:

Gradient Brushes

GDI+ expands on GDI by providing linear gradient and path gradient brushes for filling shapes, paths, and regions. Gradient brushes can also be used to draw lines, curves, and paths. When you fill a shape with a linear gradient brush, the color gradually changes as you move across the shape. For example, suppose you create a horizontal gradient brush by specifying blue at the left edge of a shape and green at the right edge. When you fill that shape with the horizontal gradient brush, it will gradually change from blue to green as you move from its left edge to its right edge. Similarly, a shape filled with a vertical gradient brush will change color as you move from top to bottom. The following illustration shows an ellipse filled with a horizontal gradient brush and a region filled with a diagonal gradient brush.

When you fill a shape with a path gradient brush, you have a variety of options for specifying how the colors change as you move from one portion of the shape to another. One option is to have a center color and a boundary color so that the pixels change gradually from one color to the other as you move from the middle of the shape towards the outer edges. The following illustration shows a path (created from a pair of Bézier splines) filled with a path gradient brush.

Cardinal Splines

GDI+ supports cardinal splines, which are not supported in GDI. A cardinal spline is a sequence of individual curves joined to form a larger curve. The spline is specified by an array of points and passes through each point in that array. A cardinal spline passes smoothly (no sharp corners) through each point in the array and thus is more refined than a path created by connecting straight lines. The following illustration shows two paths, one created by connecting straight lines and one created as a cardinal spline.

Persistent Path Objects

In GDI, a path belongs to a device context, and the path is destroyed as it is drawn. With GDI+, drawing is performed by a Graphics object, and you can create and maintain several Path objects that are separate from the Graphics object. A Path object is not destroyed by the drawing action, so you can use the same Path object to draw a path several times.

Transformations and the Matrix Object

GDI+ provides the Matrix object, a powerful tool that makes transformations (rotations, translations, and so on) easy and flexible. A matrix object works in conjunction with the objects that are transformed. For example, a Path object has a Transform method that receives the address of a Matrix object as an argument. A single 3×3 matrix can store one transformation or a sequence of transformations. The following illustration shows a path before and after a sequence of two transformations (first scale, then rotate).

Scalable Regions

GDI+ expands greatly on GDI with its support for regions. In GDI, regions are stored in device coordinates, and the only transformation that can be applied to a region is a translation. GDI+ stores regions in world coordinates and allows a region to undergo any transformation (scaling, for example) that can be stored in a transformation matrix. The following illustration shows a region before and after a sequence of three transformations: scale, rotate, and translate.

Alpha Blending

Note that in the previous figure, you can see the untransformed region (filled with red) through the transformed region (filled with a hatch brush). This is made possible by alpha blending, which is supported by GDI+. With alpha blending, you can specify the transparency of a fill color. A transparent color is blended with the background color—the more transparent you make a fill color, the more the background shows through. The following illustration shows four ellipses that are filled with the same color (red) at different transparency levels.

Support for Multiple Image Formats

GDI+ provides the Image, Bitmap, and Metafile classes, which allow you to load, save and manipulate images in a variety of formats. The following formats are supported:

  • BMP
  • GIF
  • JPEG
  • EXIF
  • PNG
  • TIFF
  • ICON
  • WMF
  • EMF

编程变得更简单:

Device Contexts, Handles, and Graphics Objects

If you have written programs using GDI (the graphics device interface included in previous versions of Windows), you are familiar with the idea of a device context (DC). A device context is a structure used by Windows to store information about the capabilities of a particular display device and attributes that specify how items will be drawn on that device. A device context for a video display is also associated with a particular window on the display. First you obtain a handle to a device context (HDC), and then you pass that handle as an argument to GDI functions that actually do the drawing. You also pass the handle as an argument to GDI functions that obtain or set the attributes of the device context.

When you use GDI+, you don't have to be as concerned with handles and device contexts as you do when you use GDI. You simply create a Graphics object and then invoke its methods in the familiar object-oriented style—myGraphicsObject.DrawLine(parameters). The Graphics object is at the core of GDI+ just as the device context is at the core of GDI. The device context and the Graphics object play similar roles, but there are some fundamental differences between the handle-based programming model used with device contexts (GDI) and the object-oriented model used with Graphics objects (GDI+).

The Graphics object, like the device context, is associated with a particular window on the screen and contains attributes (for example, smoothing mode and text rendering hint) that specify how items are to be drawn. However, the Graphics object is not tied to a pen, brush, path, image, or font as a device context is. For example, in GDI, before you can use a device context to draw a line, you must call SelectObject to associate a pen object with the device context. This is referred to as selecting the pen into the device context. All lines drawn in the device context will use that pen until you select a different pen. With GDI+, you pass a Pen object as an argument to the DrawLine method of the Graphics class. You can use a different Pen object in each of a series of DrawLine calls without having to associate a given Pen object with a Graphics object.

Two Ways to Draw a Line

The following two examples each draw a red line of width 3 from location (20, 10) to location (200,100). The first example calls GDI, and the second calls GDI+ through the C++ class interface.

Drawing a line with GDI

To draw a line with GDI, you need two objects: a device context and a pen. You get a handle to a device context by calling BeginPaint, and you get a handle to a pen by calling CreatePen. Next, you call SelectObject to select the pen into the device context. You set the pen position to (20, 10) by calling MoveToEx and then draw a line from that pen position to (200, 100) by calling LineTo. Note that MoveToEx and LineTo both receive hdc (the handle to the device context) as an argument.

HDC          hdc;
PAINTSTRUCT  ps;
HPEN         hPen;
HPEN         hPenOld;

hdc = BeginPaint(hWnd, &ps);
   hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
   hPenOld = (HPEN)SelectObject(hdc, hPen);
   MoveToEx(hdc, 20, 10, NULL);
   LineTo(hdc, 200, 100);
   SelectObject(hdc, hPenOld);
   DeleteObject(hPen);
EndPaint(hWnd, &ps);

Drawing a line with GDI+ and the C++ class interface

To draw a line with GDI+ and the C++ class interface, you need a Graphics object and a Pen object. Note that you don't ask Windows for handles to these objects. Instead, you use constructors to create an instance of the Graphics class (a Graphics object) and an instance of the Pen class (a Pen object). Drawing a line involves calling the DrawLine method of the Graphics class. The first parameter of the DrawLine method is a pointer to your Pen object. This is a simpler and more flexible scheme than selecting a pen into a device context as shown in the preceding GDI example.

HDC          hdc;
PAINTSTRUCT  ps;
Pen*         myPen;
Graphics*    myGraphics;

hdc = BeginPaint(hWnd, &ps);
   myPen = new Pen(Color(255, 255, 0, 0), 3);
   myGraphics = new Graphics(hdc);
   myGraphics->DrawLine(myPen, 20, 10, 200, 100);
   delete myGraphics;
   delete myPen;
EndPaint(hWnd, &ps);

Pens, Brushes, Paths, Images, and Fonts as Parameters

The preceding examples show that Pen objects can be created and maintained separately from the Graphics object, which supplies the drawing methods. Brush, Path, Image, and Font objects can also be created and maintained separately from the Graphics object. Many of the drawing methods provided by the Graphics class receive a Brush, Path, Image, or Font object as an argument. For example, the address of a Brush object is passed as an argument to the FillRectangle method, and the address of a Path object is passed as an argument to the DrawPath method. Similarly, addresses of Image and Font objects are passed to the DrawImage and DrawString methods. This is in contrast to GDI where you select a brush, path, image, or font into the device context and then pass a handle to the device context as an argument to a drawing function.

Method Overloading

Many of the GDI+ methods are overloaded; that is, several methods share the same name but have different parameter lists. For example, the DrawLine method of the Graphics class comes in the following forms:

Status DrawLine(IN const Pen* pen,
                IN REAL x1,
                IN REAL y1,
                IN REAL x2,
                IN REAL y2);

Status DrawLine(IN const Pen* pen,
                IN const PointF& pt1,
                IN const PointF& pt2);

Status DrawLine(IN const Pen* pen,
                IN INT x1,
                IN INT y1,
                IN INT x2,
                IN INT y2);
    
Status DrawLine(IN const Pen* pen,
                IN const Point& pt1,
                IN const Point& pt2);

All four of the DrawLine variations above receive a pointer to a Pen object, the coordinates of the starting point, and the coordinates of the ending point. The first two variations receive the coordinates as floating point numbers, and the last two variations receive the coordinates as integers. The first and third variations receive the coordinates as a list of four separate numbers, while the second and fourth variations receive the coordinates as a pair of Point (or PointF) objects.

No More Current Position

Note that in the DrawLine methods shown previously both the starting point and the ending point of the line are received as arguments. This is a departure from the GDI scheme where you call MoveToEx(hdc, x1, y1, NULL) to set the current pen position followed by LineTo(hdc, x2, y2) to draw a line starting at (x1, y1) and ending at (x2, y2). GDI+ as a whole has abandoned the notion of current position.

Separate Methods for Draw and Fill

GDI+ is more flexible than GDI when it comes to drawing the outlines and filling the interiors of shapes like rectangles. GDI has a Rectangle function that draws the outline and fills the interior of a rectangle all in one step. The outline is drawn with the currently selected pen, and the interior is filled with the currently selected brush.

hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 0, 255));
hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
Rectangle(hdc, 100, 50, 200, 80);

GDI+ has separate methods for drawing the outline and filling the interior of a rectangle. The DrawRectangle method of the Graphics class has the address of a Pen object as one of its parameters, and the FillRectangle method has the address of a Brush object as one of its parameters.

HatchBrush* myHatchBrush = new HatchBrush(
   HatchStyleCross,
   Color(255, 0, 255, 0),
   Color(255, 0, 0, 255));
Pen* myPen = new Pen(Color(255, 255, 0, 0), 3);
myGraphics.FillRectangle(myHatchBrush, 100, 50, 100, 30);
myGraphics.DrawRectangle(myPen, 100, 50, 100, 30);

Note that the FillRectangle and DrawRectangle methods in GDI+ receive arguments that specify the rectangle's left edge, top, width, and height. This is in contrast to the GDI Rectangle function, which takes arguments that specify the rectangle's left edge, right edge, top, and bottom. Also note that the constructor for the Color class in GDI+ has four parameters. The last three parameters are the usual red, green, and blue values; the first parameter is the alpha value, which specifies the extent to which the color being drawn is blended with the background color.

Constructing Regions

GDI provides several functions for creating regions: CreateRectRgn, CreateEllpticRgn, CreateRoundRectRgn, CreatePolygonRgn, and CreatePolyPolygonRgn. You might expect the Region class in GDI+ to have analogous constructors that take rectangles, ellipses, rounded rectangles, and polygons as arguments, but that is not the case. The Region class in GDI+ provides a constructor that receives a Rect object reference and another constructor that receives the address of a Path object. If you want to construct a region based on an ellipse, rounded rectangle, or polygon, you can easily do so by creating a Path object (that contains an ellipse, for example) and then passing the address of that Path object to a Region constructor.

GDI+ makes it easy to form complex regions by combining shapes and paths. The Region class has Union and Intersect methods that you can use to augment an existing region with a path or another region. One nice feature of the GDI+ scheme is that a Path object is not destroyed when it is passed as an argument to a Region constructor. In GDI, you can convert a path to a region with the PathToRegion function, but the path is destroyed in the process. Also, a Path object is not destroyed when its address is passed as an argument to a Union or Intersect method, so you can use a given path as a building block for several separate regions. This is shown in the following example. Assume that onePath is a pointer to a Path object (simple or complex) that has already been initialized.

Region  region1(rect1);
Region  region2(rect2);

region1.Union(onePath);
region2.Intersect(onePath);

GDI和GDI+的区别和联系

GDI: GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows API(Application Programming Interfac...
  • ghevinn
  • ghevinn
  • 2013年01月23日 15:16
  • 2026

GDI+环境配置与使用方法

简介:本文主要针对VC++.NET程序开发人员,如果使用VC++6.0,那么需要下载微软的GDIPLUS支持包(如果使用VS2003或以上版本则不需要下载GDIPLUS支持包了,因为它本身已包含了这些...
  • scollins
  • scollins
  • 2010年06月07日 11:06
  • 1985

GDI+缩放图片方法小结(转)

GDI+缩放图片的方法
  • shtianhai
  • shtianhai
  • 2010年07月15日 09:26
  • 5387

关于GDI+的用法及资源下载

GDI开发包:http://www.codeguru.com/gdi/GDIPlus.zip JPG危险补丁:http://download.microsoft.com/download/a/b/c...
  • cg5416
  • cg5416
  • 2005年05月16日 13:29
  • 1393

GDI+ 图像程序设计手册(word文档下载!)

 开始前,说几句废话。这些文章是我在MSDN上整理的,大家觉得有错误或很低级。请随便骂哈!本人也是菜鸟,呵呵!不怕!谢谢关注我的博客blog.csdn.net/suntaoznz 目 录 如 下 GD...
  • suntaoznz
  • suntaoznz
  • 2006年02月06日 17:20
  • 6224

C++:GDI+ 半透明的阴影效果

利用 GDI+可以很容易的描画出逼真的半透明效果的阴影。void DrawShadow(Graphics &g, GraphicsPath ButtonPath){    g.SetPageUnit(...
  • xelone
  • xelone
  • 2010年05月10日 15:48
  • 2000

加载GDI+,并且使用GDI+制作png贴图

1、加载GDI+  1)在stdafx.h中添加:    #include           using namespace Gdiplus;  2)在DLG的头文件里添加:   ...
  • yongzhen150
  • yongzhen150
  • 2014年12月03日 16:46
  • 698

用GDI+放大图片(DrawImage)时的“边界像素”问题

前人发现过类似的:)并已经有了解决方法: http://webserver2.tecgraf.puc-rio.br/~scuri/gdiplus/drawimage_scale_problem.ht...
  • crybird
  • crybird
  • 2017年02月20日 10:39
  • 468

封装GDI+函数库

在C++builder中使用GDI+的步骤有些麻烦,将常用的函数封装到一个DLL库中,直接调用。 //-------------------------------------------------...
  • chinayu2007
  • chinayu2007
  • 2015年04月29日 08:25
  • 1227

GDI+实现png图片加载

vc++加载透明png图片方法——GDI+和CImage两种 MFC项目添加GDIplus,一编译就报 VS平台不用再单独下载GDI+了 实现PNG图片加载的两种方法 一.png加载 1.定义 G...
  • greless
  • greless
  • 2017年06月07日 16:03
  • 567
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GDI+
举报原因:
原因补充:

(最多只允许输入30个字)