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
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);
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"/>
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.
There is another way to accomplish serving a dynamic image.
namespace MyApp
{
[ServiceContract]
public interface IMyService
{
[WebGet(UriTemplate = "Image.png")]
[OperationContract]
Stream ShowImage();
}
}
For the implementation:
public Stream ShowImage()
{
Bitmap image = new Bitmap(@"C:\Image.png");
Image image2 = new Bitmap(125, 125);
using (Graphics graphics = Graphics.FromImage(image2))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.DrawImage(image, 0, 0, 125, 125);
}
MemoryStream imageAsMemoryStream = new MemoryStream();
image2.Save(imageAsMemoryStream, ImageFormat.Png);
imageAsMemoryStream.Position = 0;
return imageAsMemoryStream;
}
Start the service as a regular WCF service and add the service in your app.config
(WebService = new WebServiceHost(typeof(MyService))).Open();
You can pass parameters to make it more dynamic.
I think @Lloyd's answer is a good start.
I've had problems with alpha transparencies and PNGs: Can you make an alpha transparent PNG with C#?
It is NOT possible to output image from a WebService.
Check this: http://www.c-sharpcorner.com/UploadFile/gnsrinivas1511/Webservice05112009034709AM/Webservice.aspx