41

When outputting an image to the output stream, does it require temporary storage? I get the "generic GDI+" error that is usually associated with folder permission error when saving an image to file.

The only thing I'm doing to the image is adding some text. I still get the error even when I output the image straight without modifications. For example, doing this will give me the error:

using (Bitmap image = new Bitmap(context.Server.MapPath("images/stars_5.png")))
{
    image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);
}

Everything works fine on my local machine running Windows 7 with IIS 7.5 and ASP.NET 2.0. The problem is occurring on the QA server which is running Windows Server 2003 with IIS 6 and ASP.NET 2.0.

The line that's giving the error is:

image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);

Here's the stack trace:

[ExternalException (0x80004005): A generic error occurred in GDI+.]
   System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) +378002
   System.Drawing.Image.Save(Stream stream, ImageFormat format) +36
   GetRating.ProcessRequest(HttpContext context) in d:\inetpub\wwwroot\SymInfoQA\Apps\tools\Rating\GetRating.ashx:54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Daniel
  • 648
  • 1
  • 8
  • 14

2 Answers2

90

PNGs (and other formats) need to be saved to a seekable stream. Using an intermediate MemoryStream will do the trick:

using (Bitmap image = new Bitmap(context.Server.MapPath("images/stars_5.png")))
{
   using(MemoryStream ms = new MemoryStream())
   {
      image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
      ms.WriteTo(context.Response.OutputStream);
   }
}
Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
  • This is the first answer i have seen with ms.writeto, all other solutions like this just tried httpResponseMessage response.Content =new StreamContent(ms.toarray()) which did not work for me. good job! – JD E Aug 02 '16 at 22:40
  • @Ammar it's a `System.Web.HttpContext` instance in ASP.NET. – Mark Cidade Aug 02 '16 at 23:09
10

I just would add:

Response.ContentType = "image/png";

So it can be viewed directly in the browser when it isn't within an img tag.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
oamilkar
  • 326
  • 3
  • 5