Getting Started with Dynamic Images in ASP.NET
Before you can create any images, or use any graphics commands, you must decide what you will be drawing to. In a standalone application, you will draw to one of the application's
Because your ASP.NET application does not have a window in the classic sense to which it can draw, you must create some other object to which youwill draw. In this chapter I use bitmaps, and these bitmaps are encapsulated in a Bitmap class. So, all the code samples in this chapter begin by creating a bitmap destination object for the drawing. Actually, it would be more correct to refer to this object as a surface . This is a similar concept to the DirectX notion, in which all operations in DirectX are done to a surface. So for the rest of this chapter I won't refer to a device context; instead, I will refer to either a bitmap or a surface as the destination for all drawing operations. Several bitmap constructors are available to you. But in this chapter I will exclusively use the constructor that accepts a width and a height each as integers, and pixel format argument. A pixel format argument is an enumeration that can be seen in Table 16.1. Table 16.1. The Pixel Format Enumeration
The following code fragment creates a bitmap that is 300 pixels wide and 200 pixels high. It specifies a format of 24 bits per pixel in an RGB color space. I tend to use 24-bit images because most JPG images are 24 bits per pixel. When I generate dynamic images, I usually get a more accurate rendering when I use 24 bits per pixel than I do if I use saved JPG images. You must use the System.Drawing namespace in your code. C# Bitmap newBitmap = new Bitmap( 300, 200, PixelFormat.Format24bppRgb ); VB Dim newBitmap As New Bitmap(300, 200, PixelFormat.Format24bppRgb)
After you have created a bitmap you then need to obtain a graphics object that references that bitmap. It is similar to getting a device context in Visual Basic or Visual C++ programming. It is almost identical, though, to what you do in Java. In Java, you have an object named exactly the same thing:
Graphics
. In Java, you make a method call to
getGraphics()
, and then you use the
Graphics
object for all draw operations. In ASP.NET (for a bitmap as we have created) you use the static
FromImage()
method. The
FromImage()
method takes as an argument the bitmap to which you want to draw and returns a
Graphics
object that references the bitmap. You use this Graphics object, then, for all
C# Graphics g = Graphics.FromImage( newBitmap ); VB Dim g As Graphics = Graphics.FromImage(newBitmap)
I need to
C# Pen pen = new Pen( Color.Red ); g.DrawLine( pen, 10, 14, 100, 225 ); VB Dim pen as new Pen( Color.Red ) g.DrawLine( pen, 10, 14, 100, 225 )
The same idea holds true if you want to draw
C# SolidBrush blueBrush = new SolidBrush( Color.Blue ); g.FillRectangle( blueBrush, 0, 0, 150, 100 ); VB Dim blueBrush as new SolidBrush( Color.Blue ) g.FillRectangle( blueBrush, 0, 0, 150, 100 ) And now it is time to complete this discussion of simple creation of bitmaps, obtaining a graphics, and then drawing to the Graphics object. Take a look at the code in Figure 16.1. This code draws four rectangles to a created bitmap, and then sends it out to the browser for display. The source code for the creation of the bitmap can be seen in Listing 16.1. Figure 16.1. This simple code creates a bitmap, and then draws four rectangles.
I need to make several comments about the following code fragment, and more
Figure 16.2. Here the image was output to Response.OutputStream midway into the HTML rendering process.
Listing 16.1 Simple Code That Creates and Draws to a Bitmap ObjectBitmap newBitmap = new Bitmap( 300, 200, PixelFormat.Format24bppRgb ); Graphics g = Graphics.FromImage( newBitmap ); SolidBrush blueBrush = new SolidBrush( Color.Blue ); SolidBrush redBrush = new SolidBrush( Color.Red ); SolidBrush greenBrush = new SolidBrush( Color.Green ); SolidBrush blackBrush = new SolidBrush( Color.Black ); g.FillRectangle( blueBrush, 0, 0, 150, 100 ); g.FillRectangle( redBrush, 150, 0, 150, 100 ); g.FillRectangle( greenBrush, 0, 100, 150, 100 ); g.FillRectangle( blackBrush, 150, 100, 150, 100 ); Response.ContentType="Image/Jpeg"; newBitmap.Save( Response.OutputStream, ImageFormat.Jpeg ); Another thing I want to point out is the image format enumerator that was used in the Save() method. The image format enumerator enables you to save your image in a variety of formats. They include BMP, GIF, JPG, PNG, and TIFF, among others. Table 16.2 lists the formats that are available to you in the image format enumerator. Table 16.2. The Image Format Enumerations
You must be careful when you choose an image format for your save operations. Different formats give you different results. For example, JPG images are great for photographic images, but they are not very good when your images are sharp and crisp. If your images are sharp and crisp and you save in the JPG format, you notice unexplainable artifacts that make the image look less than perfect. GIF images are very good when the desired rendering must be sharp and crisp, but GIF is limited to colors with an eight-bit pixel depth. This limits you to a total of 256 colors in a given image. That means, if you have drawn to a bitmap in a color that is not available in a saved GIF image, those colors are mapped in a way that might be somewhat undesirable. For example, if you draw a color in a
So, if your image is counting on some specific colors that are not a part of the standard GIF palette, you need to consider using JPG. On the other hand, if your image needs to be crisp and sharp, you must select GIF. It is not always an easy decision, because you might want some of the things that each format has to offer. There might be situations in your Web development when you need to create image banners at the tops of Web pages. The banners might need to be dynamically created based on the current situation. It is an easy manner to create a bitmap, draw to the bitmap, and then save it to disk. This image then can be loaded into a Web page as a banner at the top of the page.
I have created a
Figure 16.3. This application creates a simple banner based on the user's name.
You should now take a look at the code in Listing 16.2. This is the ASPX code that was created for the banner creation application. The first thing to notice is that the code makes a call to the DisplayBanner() method. This method decides whether a banner has been created for this user, and if so it displays it by outputting the appropriate HTML code at this point. If no banner has been created, then nothing is output into the HTML stream here and the user does not see a banner.
Farther down in the code you can see the
TextBox
in which users type in their names. And directly after that is the button with which users submit their
Listing 16.2 The .ASPX Code for the Banner Creation Application
<form id="WebForm2" method="post" runat="server">
<% DisplayBanner(); %>
<P>
<asp:Label id="Label1" runat="server" Font-Size="XX-Large" ForeColor="White">Banner
Now take a look at the code in Listing 16.3, which is the code behind the ASP code you just looked at. This code
Start by looking at the Page_Load() method. This method sets the Boolean variable m_bCreate to true if indeed this is a PostBack . It does this because if it is a PostBack , you can assume that the user has already typed in a name and clicked on the Submit button.
Next, you can see the
DisplayBanner()
method. If the
m_bCreated
variable is true (which happens only if this is a
PostBack
), then the HTML code necessary to display the banner is output. Notice that the actual filename is created by concatenating the word
image
with the text contained in
Label3.TEXT
followed by the .JPG extension. The
Label3.TEXT
property contains the
Listing 16.3 The C# Code for the Banner Creation Application
bool m_bCreated = false;
private void Page_Load(object sender, System.EventArgs e)
{
if( IsPostBack )
{
m_bCreated = true;
}
}
public void DisplayBanner()
{
if( m_bCreated )
{
Response.Write( "<IMG SRC=BannerImages/Image" + Label3.Text + ".jpg>\n\r" );
}
}
private void Button1_Click(object sender, System.EventArgs e)
{
DateTime dt = DateTime.Now;
Label3.Text = "" + dt.Second + "" + dt.Millisecond;
String strFilename = "BannerImages\Image" + Label3.Text + ".jpg";
String strName = TextBox1.Text;
if( strName.Length == 0 )
{
strName = "No Name";
}
Bitmap newBitmap = new Bitmap( 400, 100, PixelFormat.Format24bppRgb );
Graphics g = Graphics.FromImage( newBitmap );
SolidBrush redBrush = new SolidBrush( Color.Red );
g.FillRectangle( redBrush, 0, 0, 400, 100 );
Font newFont = new Font( "Times New Roman", 25 );
SizeF TextSize = g.MeasureString( strName, newFont );
g.DrawString( strName, newFont, new SolidBrush( Color.Blue ),
( 400 - TextSize.Width ) / 2, ( 100 - TextSize.Height ) / 2 );
newBitmap.Save( Request.MapPath( strFilename ), ImageFormat.Gif );
}
The lion's share of the code for this application can be found in the
Button1_Click()
method. This method can also be seen in Listing 16.3. The first thing that happens in this method is that the date and time are retrieved into a
DateTime
object. The seconds and
If the
Listing 16.4 The C# Code for the Banner Creation Application
bool m_bCreated = false;
str m_sImageSrc;
private void Page_Load(object sender, System.EventArgs e)
{
if( IsPostBack )
{
m_bCreated = true;
}
}
public void DisplayBanner()
{
if( m_bCreated )
{
Response.Write( "<IMG SRC='"+m_sImageSrc+ "'>\n\r" );
}
}
private void Button1_Click(object sender, System.EventArgs e)
{
m_sImageSrc="GenerateImage.aspx?TEXT="+System.URLEncode(TextBox1.Text);
}
Listing 16.5 Source for GenerateImage.aspx
String strName = Request.QueryString("TEXT");
if( strName.Length == 0 )
{
strName = "No Name";
}
Bitmap newBitmap = new Bitmap( 400, 100, PixelFormat.Format24bppRgb );
Graphics g = Graphics.FromImage( newBitmap );
SolidBrush redBrush = new SolidBrush( Color.Red );
g.FillRectangle( redBrush, 0, 0, 400, 100 );
Font newFont = new Font( "Times New Roman", 25 );
SizeF TextSize = g.MeasureString( strName, newFont );
g.DrawString( strName, newFont, new SolidBrush( Color.Blue ),
( 400 - TextSize.Width ) / 2, ( 100 - TextSize.Height ) / 2 );
Response.ContentType="Image/Gif";
newBitmap.Save( Response.OutputStream, ImageFormat.Gif );
The name is retrieved from TextBox1 and, if there is nothing in TextBox1 , the text string no name is arbitrarily assigned to it. This way, some text is always displayed in the banner, even if the user fails to type anything in. A Bitmap object is created. The width of this bitmap is 400, the height is 100, and the pixel format is 24 bits per pixel in an RGB color space. The next line of code retrieves a Graphics object from the newly created bitmap. Then, a solid red brush is created and the banner is made red with the FillRectangle() method.
Now you need to draw the user's name into the banner bitmap. First, you need to create a new font. The
Then, I call the
DrawString()
method. The first argument I give it is the user's name, the second is the font, the third is a solid brush, and the fourth and fifth are the X and Y coordinates to which I will draw. The X and Y coordinates refer to the
This application could easily be extended with many more options and features. You could enable users to create anything from banners to
|