Click here to Skip to main content
6,630,289 members and growing! (22,312 online)
Email Password   helpLost your password?
Web Development » Charts, Graphs and Images » Charts     Intermediate License: The Code Project Open License (CPOL)

Graphics Rendering with ASP Page

By Henry Tan Setiawan

Dynamically Rendering 2D graphics with ASP.NET/GDI+/C#
C#.NET 2.0, ASP.NET, GDI+, Architect, Dev, Design
Version:5 (See All)
Posted:17 Feb 2009
Views:8,454
Bookmarked:22 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
4 votes for this article.
Popularity: 2.41 Rating: 4.00 out of 5

1

2

3
4 votes, 100.0%
4

5

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.

/// <summary>
/// Draw rectangle
/// </summary>
private void DrawRectangle(Graphics g)
{
    g.Clear(Color.White);
    g.FillRectangle(Brushes.Blue, new Rectangle(0, 0, this.width, this.height));
}

/// <summary>
/// Draw triangle
/// </summary>
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)
    });
}

/// <summary>
/// Fill circle
/// </summary>
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.

/// <summary>
/// Draw shape to bitmap
/// </summary>
/// <returns>Bitmap object</returns>
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.

/// <summary>
/// Save bitmap as PNG encoded byte array
/// </summary>
/// <returns>byte arrays</returns>
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:

circle.png

http://localhost/default.aspx?shape=circle

rectangle.png

http://localhost/default.aspx?shape=rectangle

triangle.png

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Henry Tan Setiawan


Member
Henry Tan was born in a small town, Sukabumi, Indonesia, on December 7th, 1979. He obtained his Bachelor of Computer System Engineering with first class honour from La Trobe University, VIC, Australia in 2003. During his undergraduate study, he was nominated as the most outstanding Honours Student in Computer Science. Additionally, he was the holder of 2003 ACS Student Award. After he finished his Honour year at La Trobe University, on August 2003, he continued his study pursuing his doctorate degree at UTS under supervision Prof. Tharam S. Dillon. He obtained his PhD on March 2008. His research interests include Data Mining, Computer Graphics, Game Programming, Neural Network, AI, and Software Development. On January 2006 he took the job offer from Microsoft Redmond, USA as a Software Design Engineer (SDE).


What he like most? Programming!Math!Physisc!Computer Graphics!Playing Game!

What programming language?
C/C++ but started to love C#.

My website: ht4n.blogspot.com
MSN Spaces: spaces.msn.com/members/henryws
Occupation: Software Developer
Location: United States United States

Other popular Charts, Graphs and Images articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 1 of 1 (Total in Forum: 1) (Refresh)FirstPrevNext
GeneralThere is no need to use a MemoryStream PinmemberJonnyBergdahl7:56 24 Feb '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 17 Feb 2009
Editor: Deeksha Shenoy
Copyright 2009 by Henry Tan Setiawan
Everything else Copyright © CodeProject, 1999-2009
Web21 | Advertise on the Code Project