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
Rating: 4 stars4 stars4 stars4 stars4 stars / 3
September 17, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Sample Five-Reflecting and Skewing

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:

private void ImageSkewing_Click(object sender, System.EventArgs e)

{

Graphics graphics=this.CreateGraphics();

graphics.Clear(Color.White);


//define the target rendering area of the image

Point[] destination=new Point[]

{

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

graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;


//load the three pictures used as a map

Bitmap face=new Bitmap("rose.bmp");

Bitmap top=new Bitmap("flower.bmp");

Bitmap right=new Bitmap("yujinxiang.bmp");


//redefine the ordinates of the image posted in the front plane

Point[] destinationFace = new Point[]

{

new Point(LEFT,TOP),

new Point(LEFT+WIDTH, TOP),

new Point(LEFT, TOP+WIDTH)

};

//post the front side image

graphics.DrawImage(face,destinationFace);


//redefine the ordinates of the image posted in the top plane

PointF[] destinationTop= new PointF[]

{

new PointF(LEFT+WIDTH/2, TOP-WIDTH/2),

new PointF(LEFT+WIDTH/2+WIDTH, TOP-WIDTH/2),

new PointF(LEFT, TOP)

};

//post the top side image

graphics.DrawImage(top, destinationTop);


//redefine the ordinates of the image posted in the right plane

Point[] destinationRight= new Point[]

{

new Point(LEFT+WIDTH, TOP),

new Point(LEFT+WIDTH/2+WIDTH, TOP-WIDTH/2),

new Point(LEFT+WIDTH,TOP+WIDTH)

};

//post the right side image

graphics.DrawImage(right, destinationRight);

Looking more closely, you will find that the core coding lies in defining the coordinates of the cube and posting the three pictures onto it.

Sample Six-Working with Thumbnail Images

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

graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;

//load the image to be shown as thumbnails

Bitmap image=new Bitmap("flower.bmp");

//obtain the size of the current window

Rectangle client=new Rectangle(0,0,

this.ClientSize.Width,this.ClientSize.Height);

float width=image.Width;

float height=image.Height;

//get a thumbnail of specified size

Image.GetThumbnailImageAbort myCallback =

new Image.GetThumbnailImageAbort(ThumbnailCallback);

Image pThumbnail = image.GetThumbnailImage(40,40, myCallback ,IntPtr.Zero);

//use the thumbnail as a brush

TextureBrush picBrush=new TextureBrush(pThumbnail);

//fill in the window

graphics.FillEllipse(picBrush,client);

Since there are already enough comments in the code, we will not dwell on it. Figure 7 gives the associated running-time snapshot.


Figure 7-the associated running-time snapshot of the thumbnail effect


Sample Seven-Cloning an Image

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:

private void Clone_Click(object sender, System.EventArgs e)

{

Graphics graphics=this.CreateGraphics();

graphics.Clear(Color.White);


Bitmap image=new Bitmap("head.bmp");

int Height=image.Height;

int Width=image.Width;


// define the four areas that are used to divide a picture

RectangleF[] block=new RectangleF[4];

block[0]=new Rectangle(0,0,Width/2,Height/2);

block[1]=new Rectangle(Width/2,0,Width/2,Height/2);

block[2]=new Rectangle(0,Height/2,Width/2,Height/2);

block[3]=new Rectangle(Width/2,Height/2,Width/2,Height/2);


// close the four parts of an image respectively

Bitmap[] s=new Bitmap[4];

s[0]=image.Clone(block[0],PixelFormat.DontCare);

s[1]=image.Clone(block[1],PixelFormat.DontCare);

s[2]=image.Clone(block[2],PixelFormat.DontCare);

s[3]=image.Clone(block[3],PixelFormat.DontCare);

// render the four parts of the given image in turn the rendering time span is 1 second

graphics.DrawImage(s[0],0,0);


// delay to achieve the effect of rendering block by block

Thread.Sleep(1000);

graphics.DrawImage(s[1],Width/2,0);

Thread.Sleep(1000);

graphics.DrawImage(s[3],Width/2,Height/2);

Thread.Sleep(1000);

graphics.DrawImage(s[2],0,Height/2);

}

Running the above code, you will get a snapshot illustrated in Figure 8.


Figure 8-the running-time snapshot of cloning four parts of an image respectively

Note that although Figure 8 shows an integrated image, it is composed of four equal small scraps which are rendered every second.

Sample Eight-Zooming in and out

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:

Graphics graphics=this.CreateGraphics();

graphics.Clear(Color.White);

//load the image

Bitmap image=new Bitmap("photo.bmp");

//define the area to show the image

Rectangle rect=new Rectangle(0,0,image.Width,image.Height);

graphics.DrawImage(image,rect);


//set the size of the zooming out area to 80*80

graphics.TranslateTransform(image.Width+10,0);

Rectangle smallrect=new Rectangle(0,0,80,80);

//zooming out effect

graphics.DrawImage(image,smallrect,80,10,106,112,GraphicsUnit.Pixel);


graphics.TranslateTransform(0,100);

//set the size of the zooming in area to 80*80

Rectangle largerect=new Rectangle(0,0,80,80);

//zooming in effect

graphics.DrawImage(image,largerect,56,101,35,40,GraphicsUnit.Pixel);

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.

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 11 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials