【问题标题】:g.DrawImage throws out of memory exceptiong.DrawImage 抛出内存不足异常
【发布时间】:2025-12-10 13:10:01
【问题描述】:

在我的应用程序中,我正在处理大约 30 - 70 张大图像。工作是指加载、裁剪、调整大小和添加到 aviStream。每个图像最多可以有 4500p 和 10MB(处理如此大的图像会给我带来大部分内存不足的异常)。在测试时,我有时会使用较小的(每个 2500p ~ 500kB)并且内存情况要好得多。

我已将程序的架构更改为:加载一张图像,处理所需的操作,将其添加到流中,然后关闭它。并对下一张图片做同样的事情。但由于代码的复杂性和大小,我不能 100% 确定在此过程中我会处理并关闭为临时目的创建的每个位图和图像。

我有以下错误:

An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Drawing.dll

通常在裁剪图像时:

public static Image Crop(Image imgPhoto, Point xy, int width, int height) {
        Rectangle cropRect = new Rectangle(xy, new Size(width, height));
        Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);

        using (Graphics g = Graphics.FromImage(target)) {
            g.DrawImage(imgPhoto, new Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel);
        }

        return target;
    }

根据裁剪级别抛出异常,如果我裁剪大图像的一小部分,假设中间为 800x600 像素,那就更好了。如果以相反的方式裁剪,可以说创建一个 3500x2500 的图像,其中原始图像较小(空白区域将自动填充所选颜色),我大部分时间都有例外。

还有一个有趣的事情是,在第 23 张图像附近抛出异常,所以之前的图像处理得很好。

你们能给我一个如何调试的建议吗?我曾尝试扫描代码以查找未处理的图像和位图,但似乎没有找到所有这些。

因此,最大的问题是:如何一张一张地处理所有图像而不会出现异常?

【问题讨论】:

  • 我会说这是一个 Dispose 问题,但如何轻松找到它们……那是另一回事。
  • 好吧,Bitmap 没有被释放,它是从函数返回的。我假设调用代码也不会处理它。此外,如果您正在处理许多大图像,也许可以尝试重用缓冲区,而不是重新分配它。
  • 我正在部分重用它们,但我也有很多这些方法,我在一些更改后返回原始输入图像。如果我是正确的,在这种情况下只有一个图像,并且只发送一个参考。所以我不能处理它,否则我会丢失我的原始数据,对吧?
  • 在此函数中,您不会返回原始图像,而是返回一个新图像 (new Bitmap(cropRect.Width, cropRect.Height)),其中一些数据是从原始图像复制而来的。我不可能用这些很少的信息告诉你如何有效地做到这一点。 “返回”图像但避免分配图像的一种方法是在调用代码中分配“目标”,然后将其作为参数发送给所有编辑函数。
  • 非常感谢 TaW。没有尝试过,因为我认为它会删除目标的“占位符”,它将返回到其中。我不得不说,经过几次测试,它现在可以正常工作了。没有例外,并且在操作过程中 RAM 不会增加。这似乎解决了我的问题,所以再次感谢 TaW。

标签: c# image graphics out-of-memory drawimage


【解决方案1】:

如果你想在方法内创建位图,你必须在方法外使用 using 块,我的意思是你在哪里调用方法:

using (var myNewBitmap = Crop(imgPhoto, xy, width, height) ) 
{

// do whatever you want with the bitmap 

}

使用后它会处理,你不会得到异常。使用当前代码,您将来可以解决内存不足的问题。

【讨论】:

  • 好 - 这是一个比 OP 在评论他们的问题时所说的更清洁的解决方案。 (评论说在 ORIGINAL 位图上而不是在返回的位图上添加了 Dispose;没有看到他们的调用代码,不可能知道为什么会成功......)
最近更新 更多