views:

5622

answers:

5

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"&gt;
</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;}
    }
}
+1  A: 

A web service is not suitable for this. It returns a message in a specific format, typically SOAP, so it can't be an image.

Use a regular web form instead, where you remove all markup except the @page directive. Use the BinaryWrite method to write the image data to the response stream.

Example:

byte[] imageData;
using (Bitmap image = new Bitmap(10,10)) {
   using (Graphics g = Graphics.FromImage(image)) {
      g.Clear(Color.Red);
   }
   using (MemoryStream m = new MemoryStream()) {
      image.Save(m, ImageFormat.Png);
      imageData = m.ToArray();
   }
}
Response.ContentType = "image/png";
Response.BinaryWrite(imageData);
Guffa
The only change I would make to this is to use a generic handler (.ashx file). There's no need for all the page (.aspx) overhead.
Keltex
It's actually possible to do this through a web service; I do it with PDFs. The key is to return it as a byte array, reconstitute it on the other end, and then write it out with the appropriate ContentType.
Adam V
@Adam V: Then you are only using the web service as back end for a web page. You can't use the response from the web service directly, as Guy asked for.
Guffa
+9  A: 

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"]);
        Bitmap bitmap = new Bitmap(width,height);

        ...

        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();
    }

}

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

<img src="myhandler.ashx?width=10&height=10"/>
Lloyd
Yes I missed bits, if you go into the Add New Item dialog is will create a HttpHandler for you properly, or hover over IHttpHandler and select "Implement this interface".It's something like:public bool IsReusable { get { return true; } }
Lloyd
Thanks - got it! Also minor typo on the Response.ContentType and ImageFormat.PngNow just need to get it to draw something / anything...
Guy
For caching I've seen you mention you can use HttpRuntime.Cache, just dump the byte[] return from the MemoryStream in there.
Lloyd
Finally got it! Use context.Response.BinaryWrite(buffer);Lloyd, if you can correct the typo's in your answer then you get the points!!!
Guy
@Lloyd:can you make a http handler return an image? lets say a bitmap image or a byte[] buffer to a c# method (code behind file) from where it is called? I am sorry if I sound stupipd but I am new to http handlers
VP
The above example returns an image.
Lloyd
A: 

It is NOT possible to output image from a WebService.

Check this: http://www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx

NinethSense
This depends on how one views a web service. It is perfectly possible to return a binary (image) using multipart mime encoding through a C# web API. It has been done. Refer to this for starters: http://en.wikipedia.org/wiki/MIME This is not terribly challenging to do in C#
Demi
"This depends on how one views a web service." << I agree.
NinethSense
Or just return binary, as mentioned in Guffa's post. :-)
Demi
Sorry, I may have my terminology wrong (or not accurate enough for a technical community) I take it .asmx is to return xml content? I'd not heard of ashx before now.
Guy
@Guy, asmx is webservice and ashx is a handler. Ashx is almost same as aspx. It implements IHttpHandler. Check this for more details: http://stackoverflow.com/questions/619697/what-are-the-benefits-of-an-ashx-handler-file-in-asp-net. It can help you in image generation.
NinethSense
A: 

Also, depending on how you implement this, please be aware that you could be setting yourself up for a DOS attack. Generating images is not the most processor friendly thing. Please be sure to have some authentication and or caching mechanism in place to help alleviate this potential pain point.

Chad Ruppert
It's for internal / intranet use only, but caching will have to be implemented! Thanks.
Guy
+1  A: 

I think @Lloyd's answer is a good start.

I've had problems with alpha transparencies and PNGs: http://stackoverflow.com/questions/388677

Keith
Ha! I've been studying your question for the last hour. If I can just get some of the "simple stuff" right then I'm sure I can finished this off with even my numpty C# knowledge.
Guy