GDI+ (Graphics Device Interface) is the new interface for drawing Windows graphics. It is used frequently in Windows Applications but the nice thing is that they are also available in ASP.NET Web Applications.
The best way to start is with an example.
Creating graphics on the fly is not rocket science when using ASP.NET. First thing you need to do is add a using directive in the code-behind file:
using System.Drawing;
using System.Drawing.Imaging;
Next a new instance of the Bitmap object must be created in the WebForm1 class:
Bitmap Bmp;
We’ll start by creating a new gif graphic with no background defined or anything else.
You can place this in the Page_Load() event:
Bmp = new Bitmap(300, 200);
Bmp.Save(Response.OutputStream, ImageFormat.Gif);
We can see that the graphic is a rectangle with 300 width and 200 height. The graphic is saved to the OutputStream and therefore it is displayed in the web page when you compile the application. Not much to see, just a black rectangle. The important thing is that now you saw how a new graphic object is created.
We take one step at a time, and now we will change one little pixel on the graphic, just one. We do this by using the SetPixel() method of the Bitmap object:
Bmp = new Bitmap(300, 200);
Bmp.SetPixel(20, 20, Color.Yellow);
Bmp.Save(Response.OutputStream, ImageFormat.Gif);
I think it’s straightforward what this does, it sets a pixel at the specified coordinates to the specified color (in our case, yellow). 20, 20 are the coordinates of the pixel relative to the graphic. Run the web application and you can see that in the left corner there’s a small yellow dot, just as we expected.
Houston, we’ve got a problem. Maybe you spotted it or maybe not, but it has to be fixed: in Internet Explorer, for example, if you try to view the source of the page (WebForm1.aspx) you won’t be able. Also, if you try to see the name of the graphic by right clicking it and choosing Properties you’ll wonder to see that its name is WebForm1.aspx. It’s true, the name of the graphic is WebForm1.aspx and you can’t view the source of the page because actually there is no page, it’s all a graphic, just like when you open a photo in the browser.
How can we fix this? Create a new WebForm (.aspx file) and inside it link the old one (WebForm1.aspx) just like you would do with any other graphic. So in the HTML of the second WebForm – in my case I renamed it to default.aspx – add a tag like the following:
<img src="WebForm1.aspx">
Compile and open the file default.aspx. Now WebForm1.aspx is actually a graphic inside default.aspx.
Now that we fixed that problem, we can continue with drawing using GDI+. Let’s draw a line in our graphic.
First, for drawing such objects, we need to create a new instance of Graphics object. So declare this in the class of the WebForm1.aspx file:
Graphics Gfx;
Now place the following code right before the Save() method (after the SetPixel() method if you want):
Gfx = Graphics.FromImage(Bmp);
Gfx.DrawLine(Pens.Aqua, 0, 0, 300, 200);
This code creates a di qagonal from the left top corner of the rectangle to the lower right corner, it uses DrawLine() to accomplish this. The prototype of DrawLine() we are using is DrawLine(System.Drawing.Pen pen, int x1, int y1, int x2, int y2). The following graphic will help you understand how the coordinates work:
We set x1 to 0 and y1 to 0 so that the line starts in the left top corner of the rectangle. Then x2 was set to pixel number 300 and y2 to 200, the far right bottom corner of the rectangle.
To add another diagonal from the right upper corner of the rectangle to the left bottom corner, and form an X you can use the following line:
Gfx.DrawLine(Pens.Aqua, 300, 0, 0, 200);
I recommend you play with these coordinates to fully understand how they are positioned on the graphic.
Before moving one to creating something really useful using GDI+ and ASP.NET let’s see how you can write text in a graphic.
For this, we first have to create a new instance of the Font object, along with the Bitmap and Graphics object, so you should have the three:
Bitmap Bmp;
Graphics Gfx;
Font Fnt;
Inside the Page_Load() event, this is all the code we need:
Bmp = new Bitmap(300, 200);
Gfx = Graphics.FromImage(Bmp);
Fnt = new Font("Verdana", 12);
Gfx.DrawString("Hello world!", Fnt, Brushes.Yellow, 50, 50);
Bmp.Save(Response.OutputStream, ImageFormat.Gif);
You can see how the Font instance Fnt is set to the font style Verdana and to size 12. Using the Graphics object we draw the string on the graphic with yellow and at the coordinate x = 50 and y = 50. The result is the following:
Doing something useful with GDI+ and ASP.NET
Still, the purpose of this article is not to teach you GDI+, as GDI+ is a vast subject and it’s not something specific to ASP.NET because it’s being used in Windows applications also. Instead here you must see how GDI+ can be helpful when it is used with web applications. That’s why now we shall create something useful.
The code validator (name varies) is used to prevent automatic registrations from web robots or to prevent other actions that a web robot can take. We see validators almost everywhere when we have to register or use some service on the web. They are composed from a graphic which contains a small amount of characters and numbers that the user must write in a text box. If the characters match with the ones randomly generated in the graphic then it’s clear that at the other end there’s a human and not a robot. We’ll try to create this now using GDI+.
We’ll be using the same files, WebForm1.aspx which actually is the graphic and default.aspx which is the web page. I also suppose you have the using statement and the three object instances created (Bmp, Gfx and Fnt). We’ll work inside the Page_Load() event:
Random Rand = new Random();
// Create a new random number between the specified range
int RandNum = Rand.Next(10000, 99999);
Bmp = new Bitmap(90, 50);
Gfx = Graphics.FromImage(Bmp);
Fnt = new Font("Verdana", 12);
// Draw the random number
Gfx.DrawString(RandNum.ToString(), Fnt, Brushes.Yellow, 15, 15);
Bmp.Save(Response.OutputStream, ImageFormat.Gif);
This is all the code we need. A random number between 10000 and 99999 is generated and displayed as a graphic so robots can’t pass it.
Now you would only need a text box where the visitor should type the number and a few lines of code to compare it with the random value inside RandNum.
I should mention that some smart robots use character recognition to recognize the numbers in the graphic and paste them in the text box. But we can confuse the character recognition system a bit by adding some shapes in the background.
Using the following code two horizontal lines are added to the graphic that try to fool the robot:
Random Rand = new Random();
int RandNum = Rand.Next(10000, 99999);
Bmp = new Bitmap(90, 50);
Gfx = Graphics.FromImage(Bmp);
Fnt = new Font("Verdana", 12, FontStyle.Bold);
Gfx.DrawString(RandNum.ToString(), Fnt, Brushes.Yellow, 15, 15);
// Create random numbers for the first line
int RandY1 = Rand.Next(0, 50);
int RandY2 = Rand.Next(0, 50);
// Draw the first line
Gfx.DrawLine(Pens.Yellow, 0, RandY1, 90, RandY2);
// Create random numbers for the second line
RandY1 = Rand.Next(0, 50);
RandY2 = Rand.Next(0, 50);
// Draw the second line
Gfx.DrawLine(Pens.Yellow, 0, RandY1, 90, RandY2);
Bmp.Save(Response.OutputStream, ImageFormat.Gif);
What this code basically does, is draw two lines with random Y (Y1 and Y2) coordinates, so the results look similar to this one:
The visitor still recognizes the numbers but the character recognition software might have some hard time with them. There are many other things you can add to make the graphic fool even the smartest robot. You can play with adding circles and other shapes to the background, drawing the characters with random colors or sizes and so on. Or you can add some random pixels to the graphic, around 100, using the following code:
int i;
// Repeat this process 100 times
for(i = 0; i <= 100; i++)
{
// Set random position for the pixel
int RandPixelX = Rand.Next(0, 90);
int RandPixelY = Rand.Next(0, 50);
Bmp.SetPixel(RandPixelX, RandPixelY, Color.White);
}
The result being similar to the following:
What I like about GDI+ is that the only limit is your imagination, Microsoft provides you with plenty methods and properties in the GDI+ classes. If you’re fascinated about GDI+ and its uses with ASP.NET like I am, you can now explore more by developing other useful things like a chart application.
There are some books covering in detail the subject of GDI+ with .NET, and one that I can recommend is GDI+ Programming with C# by Mahesh Chand from Addison Wesley. It has 784 pages covering all you need to know about GDI+, including manipulating images.