3

When my images are being loaded from my database on my web server, I see the following error:

A generic error occurred in GDI+. at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) at System.Drawing.Image.Save(Stream stream, ImageFormat format) at MyWeb.Helpers.ImageHandler.ProcessRequest(HttpContext context)

All my code is attempting to do is load the image, can anybody take a look and let me know what I'm doing wrong?

Note - This works if I test it on my local machine, but not when I deploy it to my web server.

public void ProcessRequest(HttpContext context)
{
    context.Response.Clear();          

    if (!String.IsNullOrEmpty(context.Request.QueryString["imageid"]))         
    {
        int imageID = Convert.ToInt32(context.Request.QueryString["imageid"]);
        int isThumbnail = Convert.ToInt32(context.Request.QueryString["thumbnail"]);

        // Retrieve this image from the database
        Image image = GetImage(imageID);

        // Make it a thumbmail if requested
        if (isThumbnail == 1)
        {
            Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
            image = image.GetThumbnailImage(200, 200, myCallback, IntPtr.Zero);
        }

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

        // Save the image to the OutputStream             
        image.Save(context.Response.OutputStream, ImageFormat.Png);
    }         
    else         
    {             
        context.Response.ContentType = "text/html";             
        context.Response.Write("<p>Error: Image ID is not valid - image may have been deleted from the database.</p>");         
    } 
}

The error occurs on the line:

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

UPDATE

I've changed my code to this, bit the issue still happens:

var db = new MyWebEntities();

var screenshotData = (from screenshots in db.screenshots
                      where screenshots.id == imageID
                      select new ImageModel
                      {
                           ID = screenshots.id,
                           Language = screenshots.language,
                           ScreenshotByte = screenshots.screen_shot,
                           ProjectID = screenshots.projects_ID
                      });

foreach (ImageModel info in screenshotData) 
 {
    using (MemoryStream ms = new MemoryStream(info.ScreenshotByte))
    {
         Image image = Image.FromStream(ms);

         // Make it a thumbmail if requested
         if (isThumbnail == 1)
         {
              Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);
              image = image.GetThumbnailImage(200, 200, myCallback, IntPtr.Zero);
         }

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

         // Save the image to the OutputStream             
         image.Save(context.Response.OutputStream, ImageFormat.Png);

    } }

Thanks.

Jimmy Collins
  • 3,294
  • 5
  • 39
  • 57

1 Answers1

2

Probably for the same reason that this guy was having problems - because the for a lifetime of an Image constructed from a Stream, the stream must not be destroyed.

So if your GetImage function constructs the returned image from a stream (e.g. a MemoryStream) and then closes the stream before returning the image then the above will fail. My guess is that your GetImage looks a tad like this:

Image GetImage(int id)
{
    byte[] data = // Get data from database
    using (MemoryStream stream = new MemoryStream(data))
    {
        return Image.FromStream(data);
    }
}

If this is the case then try having GetImage return the MemoryStream (or possibly the byte array) directrly so that you can create the Image instance in your ProcessRequest method and dispose of the stream only when the processing of that image has completed.

This is mentioned in the documentation but its kind of in the small print.

Community
  • 1
  • 1
Justin
  • 84,773
  • 49
  • 224
  • 367
  • Hi Justin, I think I've changed my code to avoid this, but I still see the issue - could you take a look in my updated question? Also, it's weird that this works on my dev box, but not when I deploy it to a server? – Jimmy Collins Nov 28 '11 at 16:43
  • @JimmyC Not sure then, are the images **very** large? GDI+ seems to impose a height limit of 64K. Alternatively do you know if this only happens for thumbnails? Also can you be sure that `ThumbnailCallback` is not throwing an exception? – Justin Nov 28 '11 at 16:52
  • The images are quite small. This happens on both thumbnails & normal size images. It seems to me like a config issue, due to the fact it works on my local machine, but I'm not sure what type of config issue could cause this error. – Jimmy Collins Nov 28 '11 at 16:55