views:

110

answers:

2

This code works great for generating thumbnails, but when given a very large (100MB+) TIFF file, it throws OutOfMemoryExceptions. When I do it manually in Paint.NET on the same machine, it works fine. How can I improve this code to stop throwing on very large files?

In this case I'm loading a 721MB TIF on a machine with 8GB RAM. The Task Manager shows 2GB used so something is preventing it from using all that memory. Specifically it throws when I load the Image to calculate the size of the original. What gives?

/// <summary>Creates a thumbnail of a given image.</summary>
/// <param name="inFile">Fully qualified path to file to create a thumbnail of</param>
/// <param name="outFile">Fully qualified path to created thumbnail</param>
/// <param name="x">Width of thumbnail</param>
/// <returns>flag; result = is success</returns>
public static bool CreateThumbnail(string inFile, string outFile, int x)
{
  // Mathematically determine Y dimension
  int y;
  using (Image img = Image.FromFile(inFile)) // Exception thrown
      y = (int)((double)img.Height * ((double)x / (double)img.Width));

  // Make thumbnail     
  using (Bitmap bmp = new Bitmap(inFile)) 
    using (Bitmap thumb = new Bitmap((Image)bmp, new Size(x, y))) 
      using (Graphics g = Graphics.FromImage(thumb)) {
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.InterpolationMode = InterpolationMode.High;
        g.CompositingQuality = CompositingQuality.HighQuality;
        ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()[1];
        EncoderParameters ep2 = new EncoderParameters(1);
        ep2.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
        g.DrawImage(bmp, new Rectangle(0,0,thumb.Width, thumb.Height));
        try {
          thumb.Save(outFile, codec, ep2);
          return true; }
        catch { return false; }
      }
}
A: 

Have you tried with FastImageGDIPlus. It has worked well for me - but I've never tried loading a 721 MB file.

stackoverflow
+1  A: 

My wild guess is that, you are running it as a 32-bit application. Which limits your app's memory usage to a theoretical 2 GB, which is really more like 1.5 GB empirically.

Anzurio
Occurs both in Prod in a .NET 4.0 app pool, IIS 6, x64 OS; and in debug on an x64 machine with vs2010 rc x64... not sure how else to verify that...
tsilb
If you are really running the process in an Windows x64 env, you can verify whether the app is running as x86 by opening your task manager and locating your app's process. If it has no *32, my wild guess is wrong.
Anzurio
Dang, you're right. Looks like 64-bit can be done in VS but it makes debugging near impossible. How about a way to make it work from IIS?
tsilb