【问题标题】:Why does this thumbnail generation code throw OutOfMemoryException on large files?为什么这个缩略图生成代码会在大文件上抛出 OutOfMemoryException?
【发布时间】:2011-01-29 23:02:11
【问题描述】:

此代码非常适合生成缩略图,但是当给定一个非常大 (100MB+) 的 TIFF 文件时,它会抛出 OutOfMemoryExceptions。当我在同一台机器上的 Paint.NET 中手动执行此操作时,它工作正常。如何改进此代码以停止抛出非常大的文件?

在这种情况下,我将在具有 8GB RAM 的机器上加载 721MB TIF。任务管理器显示已使用 2GB,因此有些东西阻止它使用所有内存。具体来说,当我加载图像以计算原始大小时,它会抛出。什么给了?

/// <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; }
      }
}

【问题讨论】:

  • 这种大小的每张图像都会发生这种情况,还是只是特定实例?我知道我从 GDI 获得了某些图像的 OOM,无论大小,它通常最终导致我没有跳过正确的 GDI 箍来处理手头的流。
  • 每个非常大的图像,JPG 或 TIF。主要是 TIF,因为那是我的大部分“图像库”。非常适合 100MB 左右的文件,而且我的一些 TIF 进入 GB。
  • tsilb:我剪掉了验证代码(因为它没有触及文件)并压缩格式以使代码块不那么令人生畏。如果您认为这些更改影响了任何重要内容,请回滚。
  • 你能找到导致 OOM 异常的位吗?从 inFile 加载,从现有的位图创建新的位图,执行 DrawImage,执行保存?
  • 是的,不小心把那部分编辑掉了——重新添加了“抛出异常”注释(加载图像以计算 Y 尺寸)——我注意到在重新检查代码时我可以做一些重构。

标签: c# graphics thumbnails out-of-memory


【解决方案1】:

我的猜测是,您将它作为 32 位应用程序运行。这将您应用的内存使用量限制在理论上的 2 GB,实际上更像是 1.5 GB。

【讨论】:

  • 在 .NET 4.0 应用程序池、IIS 6、x64 操作系统的 Prod 中发生;并在使用 vs2010 rc x64 的 x64 机器上调试...不知道如何验证...
  • 如果您确实在 Windows x64 环境中运行该进程,您可以通过打开任务管理器并找到您的应用程序的进程来验证该应用程序是否以 x86 方式运行。如果它没有*32,我的猜测是错误的。
  • 当,你是对的。看起来 64 位可以在 VS 中完成,但它使调试几乎不可能。怎么样让它从 IIS 工作?
【解决方案2】:

你试过FastImageGDIPlus。它对我来说效果很好 - 但我从未尝试过加载 721 MB 的文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多