Introduction
In this article, I am going to show you how to write a simple ASP.NET page that can dynamically render a PNG image. If you are thinking of writing a web charting application, this article will give you the basic skills of rendering graphics with ASP.NET/C# and Win32 GDI+.
Background
If you are developing a Windows form .NET application, rendering graphics to a Windows Form is relatively trivial. The common technique is to override the OnPaint()
method of the Windows Form and uses the Graphics
object to draw or render graphics. It is however, not quite a trivial task if you would like to do it on the Web/ASP.NET application.
The example below shows you how you can use GDI+ graphics library to render graphics to a Bitmap
surface and render the graphics as a PNG file and return the PNG file as a response to a web request.
Rendering Graphics with GDI+
The following functions show how you can draw primitive shapes using GDI+ System.Drawing.Graphics
object.
private void DrawRectangle(Graphics g)
{
g.Clear(Color.White);
g.FillRectangle(Brushes.Blue, new Rectangle(0, 0, this.width, this.height));
}
private void DrawTriangle(Graphics g)
{
g.Clear(Color.White);
g.FillPolygon(
Brushes.Orange,
new PointF[]
{
new PointF(0, this.height),
new PointF(this.width, this.height),
new PointF(this.width/2, 0)
});
}
private void DrawCircle(Graphics g)
{
g.Clear(Color.White);
g.FillEllipse(Brushes.Red, 0, 0, this.width, this.height);
}
Rendering Graphics into Bitmap Surface
The GDI+ Graphics
object requires a drawing surface to render graphics to. The default drawing surface is the screen buffer. However, in our case, we want to render graphics to a Bitmap
surface. The DrawToBitmap()
function below shows how to draw graphics to a Bitmap
surface. When we create the Bitmap
, we need to specify the surface width
and height
.
private Bitmap DrawToBitmap()
{
Bitmap bmp = new Bitmap(this.width, this.height, PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(bmp))
{
switch (this.myShape)
{
case Shapes.Circle:
this.DrawCircle(g);
break;
case Shapes.Rectangle:
this.DrawRectangle(g);
break;
case Shapes.Triangle:
this.DrawTriangle(g);
break;
}
}
return bmp;
}
Response to WebRequest
Once we render the graphics to the Bitmap
, we can respond to the web request with the Response.BinaryWrite()
method. The argument to BinaryWrite
is a byte array. In order to get the response as a PNG image, we need to convert the Bitmap
into a byte array.
Here is how you can convert the Bitmap
into a byte array.
public byte[] Render()
{
Rectangle region = new Rectangle(0, 0, this.width, this.height);
using (Bitmap bitmap = this.DrawToBitmap())
{
using (MemoryStream imageStream = new MemoryStream())
{
bitmap.Save(imageStream, ImageFormat.Png);
byte[] buffer = new byte[imageStream.Length];
imageStream.Seek(0, SeekOrigin.Begin);
imageStream.Read(buffer, 0, buffer.Length);
return buffer;
}
}
}
Finally, you can send a PNG image as the response to the browser using the Response.BinaryWrite()
function. If you want to use a different image encoding such as JPEG, you can specify ImageFormat.Jpeg
when calling bitmap.Save()
.
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "image/png";
Canvas myCanvas = new Canvas();
byte[] data;
if (Request.QueryString.Count != 0)
{
string shape = Request.QueryString["shape"];
if (shape.Equals("triangle", StringComparison.InvariantCultureIgnoreCase))
{
myCanvas.MyShape = Canvas.Shapes.Triangle;
}
else if (shape.Equals("rectangle", StringComparison.InvariantCultureIgnoreCase))
{
myCanvas.MyShape = Canvas.Shapes.Rectangle;
}
else
{
myCanvas.MyShape = Canvas.Shapes.Circle;
}
}
data = myCanvas.Render();
Response.BinaryWrite(data);
}
You can run the example given and if you publish the ASP.NET project to a local IIS web server (http://localhost/default.aspx), you can see the ASP.NET page renders circle/rectangle/triangle by running the following on your browser:
http://localhost/default.aspx?shape=circle
http://localhost/default.aspx?shape=rectangle
http://localhost/default.aspx?shape=triangle
Points of Interest
In this article, you learnt how to use GDI+ to render graphics into a Bitmap
surface. You also learnt how to send a PNG image as a WebResponse
using WebRequest.BinaryWrite()
function.
History
- 17th February, 2009: Initial post