Create PNG image with C# HttpHandler webservice

Guy picture Guy · May 20, 2009 · Viewed 31.2k times · Source

I'd like to be able to create a simple PNG image, say of a red square using a c# web based service to generate the image, called from an <img src="myws.ashx?x=100> HTML element.

some example HTML:

<hmtl><body>
     <img src="http://mysite.com/webservice/rectangle.ashx?size=100">
</body></html>

Is there is anyone who can cobble together a simple (working) C# class just to get me started? Once off and going I'm sure I can finish this off to actually do what I want it to do.

  • End game is to create simple Red/Amber/Green (RAG) embedded status markers for a data driven web page that shows performance metrics etc*
  • I'd like it to use PNG's as I anticipate using transparency in the future*
  • ASP.NET 2.0 C# solution please... (I don't have a production 3.5 box yet)

tia

SOLUTION

rectangle.html

<html>
<head></head>
<body>
    <img src="rectangle.ashx" height="100" width="200">
</body>
</html>

rectangle.ashx

<%@ WebHandler Language="C#" Class="ImageHandler" %>

rectangle.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

public class ImageHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        int width = 600; //int.Parse(context.Request.QueryString["width"]);
        int height = 400; //int.Parse(context.Request.QueryString["height"]);

        Bitmap bitmap = new Bitmap(width,height);

        Graphics g = Graphics.FromImage( (Image) bitmap );
        g.FillRectangle( Brushes.Red, 0f, 0f, bitmap.Width, bitmap.Height );    // fill the entire bitmap with a red rectangle

        MemoryStream mem = new MemoryStream();
        bitmap.Save(mem,ImageFormat.Png);

        byte[] buffer = mem.ToArray();

        context.Response.ContentType = "image/png";
        context.Response.BinaryWrite(buffer);
        context.Response.Flush();
    }

    public bool IsReusable {
        get {return false;}
    }
}

Answer

Lloyd picture Lloyd · May 20, 2009

Web services, especially SOAP expect things like an XML envelope with the details of the call in. You'd be better off using a HttpHandler.

Something like this:

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

public class ImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        int width = int.Parse(context.Request.QueryString["width"]);
        int height = int.Parse(context.Request.QueryString["height"]);

        using (Bitmap bitmap = new Bitmap(width,height)) {

            ...

            using (MemoryStream mem = new MemoryStream()) {
                bitmap.Save(mem,ImageFormat.Png);
                mem.Seek(0,SeekOrigin.Begin);

                context.Response.ContentType = "image/png";

                mem.CopyTo(context.Response.OutputStream,4096);
                context.Response.Flush();
            }
        }
    }

}

This is very rough of course. You'd call it then:

<img src="myhandler.ashx?width=10&height=10"/>