Question

It look desceptively easy to use System.Drawing to create thumbnails in your ASP.NET application. But MSDN tells you:

Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.

I'm seeing intermittented 'out of memory' errors within this type of GDI+ code. I'm beginning to suspect this is the cause.

How ARE people doing server side image manipulation? Can anyone recommend any alternative that WON'T blow up my server?

The relevant code below. The exception intermittently happens in System.Drawing.Graphics.DrawImage. I've just inherited this project, so I'd need to check the logs to see how often this is being hit / how often we get an exception...

public byte[] Resize(int newWidth, int newHeight, Image orignalImage)
{
    Bitmap bitmap = new Bitmap(newWidth, newHeight);
    Graphics g = Graphics.FromImage(bitmap);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

    Rectangle r = new Rectangle(0, 0, newWidth, newHeight);
    g.DrawImage(orignalImage, r, r.X, r.Y, orignalImage.Width, orignalImage.Height, GraphicsUnit.Pixel);

    MemoryStream stream = new MemoryStream();
    bitmap.Save(stream, ImageFormat.Jpeg);

    // clean up memory leaks
    if (bitmap != null)
    {
        bitmap.Dispose();
        bitmap = null;
    }
    if (g != null)
    {
        g.Dispose();
        g = null;
    }


    return stream.ToArray();
}

UPDATE: I've searched thru the whole project for anywhere we are using GDI+ and put using() { } around everything that's IDisposable. I haven't seen one 'out of memory' exception since I did this.

Was it helpful?

Solution

Assuming you will be doing "stuff" per request, the issues might be

  1. Processor intensive operation: manipulation of images, which could take time.

  2. In case you are saving the file, it will lead to disk issues.

  3. You can consider using HTTP handlers,

  4. Disposing System.Drawing objects should be a priority(using(){} statement )

  5. Asynchronous Pages can be explored here.

OTHER TIPS

Why don't you set up a separate work server that is exposed through a web service.

I would recommend you put some exception handling code around these operations so that you're guaranteed to dispose of your GDI+ objects. Good practice to close your streams too ... although to my knowledge MemoryStream object is managed so should close itself when GC'd.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top