Why does this thumbnail generation code throw OutOfMemoryException on large files?

Posted by tsilb on Stack Overflow See other posts from Stack Overflow or by tsilb
Published on 2010-03-21T03:42:42Z Indexed on 2010/03/21 3:51 UTC
Read the original article Hit count: 450

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)
{
 // Validation - assume 16x16 icon is smallest useful size. Smaller than that is just not going to do us any good anyway. I consider that an "Exceptional" case.
 if (string.IsNullOrEmpty(inFile)) throw new ArgumentNullException("inFile");
 if (string.IsNullOrEmpty(outFile)) throw new ArgumentNullException("outFile");
 if (x < 16) throw new ArgumentOutOfRangeException("x");
 if (!File.Exists(inFile)) throw new ArgumentOutOfRangeException("inFile", "File does not exist: " + inFile);

 // Mathematically determine Y dimension
 int y;
 using (Image img = Image.FromFile(inFile)) {     // OutOfMemoryException
  double xyRatio = (double)x / (double)img.Width;
  y = (int)((double)img.Height * xyRatio); }

 // All this crap could have easily been Image.Save(filename, x, y)... but nooooo....
 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 = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    System.Drawing.Imaging.ImageCodecInfo codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[1];
    System.Drawing.Imaging.EncoderParameters ep2 = new System.Drawing.Imaging.EncoderParameters(1);
    ep2.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.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; } }
}

© Stack Overflow or respective owner

Related posts about thumbnail

Related posts about c#