More Examples of Simplified Image Processing in GDI+
In the first part of this series, I explained why image processing in GDI+ is much easier than it was in GDI, and began to show you some examples of image processing tasks to illustrate the point. In this article, I will pick up where I left off, focusing on the DrawImage method.
Contributed by Xianzhong Zhu Rating: / 3 September 17, 2008
When using the DrawImage method to render an image, you can specify the upper left corner, upper right corner, and the bottom left corner of a source image. Corresponding to the original coordinates, the three locations in fact specify the mapping mode of the initial image at the target area, and the three points decide the final rendering position of the image.
Suppose the upper left corner, upper right corner, and the bottom left corner of a source image are respectively (0,0), (100,0), and (0,50), then if the coordinates of the three points are reset to (200,20), (110,100), and (250,30), then not only the rendering area will change but also the outlook of the image will be modified. Figure 5 gives the related sketch map.
Figure 5-the image map sketch
To draw the two pictures displayed in Figure 5, you can use the following code snippet:
new Point(200, 20), //the upper left corner coordinate of the source image
new Point(110, 100), //the upper right corner coordinate of the source image
new Point(250, 30) //the bottom left corner coordinate of the source image
};
Bitmap image=new Bitmap("Stripes.bmp");
//render the original image
graphics.DrawImage(image, 0, 0);
//draw the new image
graphics.TranslateTransform(image.Width,0);
graphics.DrawImage(image, destination);
}
To gain a more complex and detailed understanding of image flipping, reflecting, and skewing, let us see another example of how to achieve cubic mapping.
As for cubic mapping, it in fact refers to posting images on the six planes of a cube, as is shown in Figure 6.
Figure 6-the cubic mapping effect
Those who have become familiar with GDI programming know that achieving cubic mapping may be difficult. However, with the help of the mapping support offered by GDI+, you will find it easy to tackle this kind of problem.
As indicated above, with the help of GDI+'s support in rotating, reflecting, and skewing images, you can display a picture inside any close region (here it's a parallelogram), and at the same time keep the edge of the picture consistent with the target area. As is well known, when you draw a cube on the screen, all the planes of the cube are displayed in the form of two-dimensional parallelograms, and only three planes can be seen. That is to say, to achieve the result of mapping a cube, we essentially draw three images onto the three related parallelograms.
Next, you can find out the how-tos in accomplishing the effect shown in Figure 6.
int WIDTH=200;
int LEFT=200;
int TOP=200;
Graphics graphics=this.CreateGraphics();
//use white as the background
graphics.Clear(Color.White);
//set up the interpolation mode-HighQualityBicubic
In the commonly used picture viewer applications, such as AcdSee, Windows Explorer, a thumbnail gives an outline of a real image. Using GDI+, you can easily achieve the purpose of rendering a thumbnail of an image.
The following shows the signature of the GetThumbnailImage() method:
// Summary:
// Returns a thumbnail for this System.Drawing.Image.
// Parameters:
// thumbWidth:
// The width, in pixels, of the requested thumbnail image.
// thumbHeight:
// The height, in pixels, of the requested thumbnail image.
// callback:
// A System.Drawing.Image.GetThumbnailImageAbort delegate. In GDI+ version 1.0,
// the delegate is not used. Even so, you must create a delegate and pass a
// reference to that delegate in this parameter.
// callbackData:
// Must be System.IntPtr.Zero.
// Returns:
// An System.Drawing.Image that represents the thumbnail.
public Image GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData);
As shown from the above definition, a thumbnail is based upon a whole image; it is in fact only a copy of the original image. In addition, the user can specify the size of a thumbnail of an image-maybe even larger than the original. Next, let us take a close look at a related sample application.
Graphics graphics=this.CreateGraphics();
graphics.Clear(Color.White);
//set up the interpolation mode-HighQualityBicubic
Clone, i.e. "copy," is a new concept introduced in GDI+. You can wholly or partially clone a picture, which is performed by the Clone() method of the Bitmap class (or other classes, such as Image). To perform a partial cloning, you have to specify the related local coordinates.
The clone function of a picture is very important in scenarios requiring special image effects. Take for example, if you want to render an image by mosaic at random, the local operation becomes of great importance. Similarly, under conditions that require rendering an image piece by piece with delay, it also needs partial image handling.
In this sample, we achieve the effect of splitting a big image into four equal pieces, then clone them, and finally render them sequentially. Now let us look at the related code, as follows:
In this sample, we will continue to work with the DrawImage() function, but to achieve the zooming in and out effect. First, let us quickly examine the signature of this function, as follows:
// Summary:
// Draws the specified portion of the specified System.Drawing.Image at the
// specified location and with the specified size.
// Parameters:
// image:
// System.Drawing.Image to draw.
// destRect:
// System.Drawing.Rectangle structure that specifies the location and size of
// the drawn image. The image is scaled to fit the rectangle.
// srcX:
// The x-coordinate of the upper-left corner of the portion of the source image
// to draw.
// srcY:
// The y-coordinate of the upper-left corner of the portion of the source image
// to draw.
// srcWidth:
// Width of the portion of the source image to draw.
// srcHeight:
// Height of the portion of the source image to draw.
// srcUnit:
// Member of the System.Drawing.GraphicsUnit enumeration that specifies the
// units of measure used to determine the source rectangle.
// Exceptions:
// System.ArgumentNullException:
// image is null.
public void DrawImage(Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit);
Note that the source area and the target area of the DrawImage() function are irrelevant. If the source area is bigger the target area, invoking the DrawImage() function will result in a zooming out result; otherwise, we will see a converse zooming in effect. Now, let us start to write the application whose crucial code is listed below:
Now, press F5 to launch this sample, and you will see the running time snapshot as shown in Figure 9.
Figure 9-the running time snapshot to achieve the zooming in and out effects
Apparently, in Figure 9, the head of Gandalf is zoomed out, while the head of Aragorn is zoomed in. Regrettably, herein we have only utilized the hard-code means. However, if you continue to add mouse dragging to select certain shapes to zoom into or out from your target, that would be better.
Summary
The two most important classes in GDI+ are Image and Bitmap; they greatly simplify image processing. Moreover, to handle a Metafile file it is highly recommended that you fall back on the Metafile class. By leveraging several interpolating algorithms, you can easily control the different kinds of rendering qualities. At last, we've discussed the GetThumbnailImage() method as well as Clone() to achieve other kinds of special image effects.