GDI+ Programming
Before we dive any deeper into the application programming, let's look at some basic concepts of the GDI+ library. |
6.5.1 What Is GDI+?
GDI+ is an object-oriented library for application programmers to support the task of graphics programming. The origin of the GDI+ library can be found in the GDI (Graphical Device Interface), which is part of the Windows operating system. More specifically, GDI+ is a wrapper around the system's GDI calls. The goal of the GDI library is to shield the application developer from some of the system details by providing an additional layer of abstraction. For example, developers program the functionality of "drawing" on the screen in the same way they program "drawing" on a printer. It does not matter whether the memory in which the graphic is defined is printed or is shown on the screen. GDI takes care of the differences.
One of the major advantages of GDI+ compared with GDI is that GDI+ is fully integrated into the .NET Framework as an object-oriented library.
6.5.2 GDI+ Namespaces
To support the application programmer, GDI+ defines six namespaces in System.Drawing.dll:
- System.Drawing: This namespace provides the basic graphics functionality. It defines drawing surfaces, images, fonts, colors, brushes, and pens.
- System.Drawing.Text: Additional functionality for advanced font usage is defined in this namespace.
- System.Drawing.Imaging: This namespace provides additional functionality for advanced imaging operations.
- System.Drawing.Drawing2D: This namespace defines advanced vector graphics and raster functionality.
- System.Drawing.Printing: Print and print-preview functionalities are provided in this namespace.
- System.Drawing.Design: This namespace defines functionality for design-time support of custom controls.
The various namespaces will be explained in more detail at the time they are used.
The main features of the GDI+ library can be summarized as follows:
- It supports three drawing surfaces (memory, screen, and printer).
- It supports text drawing.
- It contains image and bitmap functionality.
- It lets you execute two-dimensional graphics primitives and transformations on any drawing surface.
- It provides object-oriented interfaces.
- It extends the capabilities of GDI by supporting more image formats, additional transformations, alpha blending, and gradients.
- It is interoperable with any .NET application.
6.5.3 The Basics of GDI+
This section defines a basic vocabulary that is needed for the implementation of GDI+ functionality. It is not supposed to be a tutorial on GDI+ but rather gives you a brief introduction to help you understand the GDI+ functionality used in the sample project and to help you build a common vocabulary.
The Drawing Surface
GDI+ defines three drawing surfaces: memory, screen, and printer. Each is characterized by the following elements:
- Size: The size of the drawing surface is measured in pixels, where a pixel is a square entity and the smallest possible drawing unit. After you create a drawing surface, you can query the size and in some cases change it.
- Resolution: The resolution of a drawing surface is usually measured in dots per inch (DPI) or in pixels per inch (PPI). A given value describes a square area, with the value of the number of pixels in the horizontal and vertical directions per inch.
- Color: The color depth describes the capability of displaying various colors. GDI+ internally represents each color with three values. The red, green, and blue (RGB) components describe the color of each pixel. Each color component in GDI+ can have a value between 0 and 255. This results in the capability of displaying a maximum of 16,777,216 colors, which corresponds to a color depth of 24 bits. In case of incompatibility of the drawing surface with the currently used color scheme, GDI+ tries to adapt the colors through a process called dithering. Dithering uses alternating colors for two adjacent pixels to create the illusion of a color that cannot be drawn because the color depth is not supported by the drawing surface. In some cases, this behavior is visually jarring. You can avoid dithering by asking the system for the nearest color that is supported. In addition, GDI+ provides an alpha component for each pixel, which can be used to define the transparency or opacity of a color, something that can be used for special effects.
Table 6.5 shows the three drawing surfaces along with their characteristics.
Drawing Surface |
Resolution |
Size |
Color Depth |
---|---|---|---|
Memory |
The default resolution for images allocated in memory is 96 DPI. If an image is loaded from a file, the resolution is also read from the file. The resolution can be changed at any time. |
The size is specified when the surface is created. If an image is loaded from a file, its size is also read from the file. |
Monochrome, grayscale, color map, 16- to 64-bit, and alpha values are the possible parameters for images allocated in memory. |
Screen |
96 DPI |
Size depends on the client area of the window that is displayed on the screen. |
Usually 24 bits. If necessary, dithering is used for drawing the image on the screen. |
Printer |
Resolution depends on the printer and therefore depends on the printer driver. Can be changed if the printer driver allows changing resolution. |
Size depends on the page size that is supported by the printer driver. |
Typically 24 bits, but GDI+ and the printer driver are responsible for drawing the image on a printer surface. |
The drawing surfaces are encapsulated in the GDI+ Graphics class. If you have some exposure to GDI programming, you will realize that the Graphics class is associated with a specific device context.
The Graphics class lets you query for details of the instantiated drawing surface, such as its size and resolution. In addition, the Graphics class provides operations to transform images (for example, to rotate, flip, and clip) and to draw basic graphics primitives onto the drawing surface (for example, lines, ellipses, rectangles, text, and images); these primitives are then displayed on the screen, printed, or written into memory. For a comprehensive list of methods provided by the Graphics class, please refer to the MSDN help pages.
The Coordinate System
To work with images, graphics, and other operations related to image processing, it is very important to understand the basic coordinate system on which all the GDI+ operations are based. The GDI+ coordinate system is raster-based. In this case, raster-based means that the image is stored as a two-dimensional grid. Within this grid, the upper-left corner is defined as the origin of the coordinate system.
Graphics primitives such as lines, rectangles, and circles are defined by two points within the coordinate system. For lines, these points are the start and end points, and for rectangles and circles they are the coordinates of the upper-left and lower-right corners of the bounding rectangle (in the case of the rectangle, this is the actual rectangle).
What happens if the graphics primitive that is drawn does not exactly fit into the raster grid? This is shown in Figure 6.8. In that case, when you're drawing a diagonal line, a stair-step effect might become visible because of the limited resolution. This stair-step effect is called aliasing. To make this effect less visible, you can use a smoothing technique called antialiasing. This is also shown in the example in Figure 6.8.
Figure 6.8. GDI+ Basics
Antialiasing is also used by GDI+ if the application provides coordinates in floating point numbers instead of integers.
GDI+ Pens and Brushes
To draw the graphics, GDI+ defines various pens and brushes. Pens are used to draw points, lines, and the outlines of shapes, whereas brushes are used to fill shapes with patterns and colors. The most important properties of pens and brushes are listed in Table 6.6.
The various properties will be explained at their first use in the up coming chapters. Definitions are also available in the MSDN documentation.
Drawing Object |
Properties |
---|---|
Pen |
Width, patterns or styles, end styles (arrows and other shapes), join styles |
Brush |
Textures, gradient brushes, hatch (to fill a region with a pattern) |