【问题标题】:Brightness method shows "Out of memory" exception亮度方法显示“内存不足”异常
【发布时间】:2012-04-11 06:31:59
【问题描述】:

要在 c#.net 4 中更改图像的亮度,我使用了以下方法。

 public void SetBrightness(int brightness)
    {
        imageHandler.RestorePrevious();
        if (brightness < -255) brightness = -255;
        if (brightness > 255) brightness = 255;
        ColorMatrix cMatrix = new ColorMatrix(CurrentColorMatrix.Array);
        cMatrix.Matrix40 = cMatrix.Matrix41 = cMatrix.Matrix42 = brightness / 255.0F;
        imageHandler.ProcessBitmap(cMatrix);
    } 

      internal void ProcessBitmap(ColorMatrix colorMatrix)
          {
            Bitmap bmap = new Bitmap(_currentBitmap.Width, _currentBitmap.Height)

            ImageAttributes imgAttributes = new ImageAttributes();
            imgAttributes.SetColorMatrix(colorMatrix);
            Graphics g = Graphics.FromImage(bmap);
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.DrawImage(_currentBitmap, new Rectangle(0, 0, _currentBitmap.Width,   
            _currentBitmap.Height), 0, 0, _currentBitmap.Width, 
            _currentBitmap.Height,  GraphicsUnit.Pixel, imgAttributes);
            _currentBitmap = (Bitmap)bmap.Clone();


        }

如果多次更改亮度,则会显示“内存不足”异常。我曾尝试使用“Using block”,但很顺利。

有什么想法吗?

请看链接 http://www.codeproject.com/Articles/227016/Image-Processing-using-Matrices-in-Csharp 并建议在方法中是否可以进行任何类型的优化(旋转、亮度、裁剪和撤消)。

【问题讨论】:

  • 您可能忘记在 Bitmap 对象上调用 Dispose()。它们占用大量非托管内存,垃圾收集器不会让您摆脱麻烦。

标签: c#-4.0 memory-leaks out-of-memory


【解决方案1】:

我已经从 CodeProject 下载了项目,并且修复了内存泄漏。您需要在覆盖之前处置 Graphics 对象和 _currentBitmap 图像。另外,您需要停止使用.Clone

如果你用这段代码替换ProcessBitmap函数的内容,内存泄漏就没有了:

internal void ProcessBitmap(ColorMatrix colorMatrix)
{
  Bitmap bmap = new Bitmap(_currentBitmap.Width, _currentBitmap.Height);
  ImageAttributes imgAttributes = new ImageAttributes();
  imgAttributes.SetColorMatrix(colorMatrix);
  using (Graphics g = Graphics.FromImage(bmap))
  {
      g.InterpolationMode = InterpolationMode.NearestNeighbor;
      g.DrawImage(_currentBitmap, new Rectangle(0, 0, _currentBitmap.Width, _currentBitmap.Height), 0, 0, _currentBitmap.Width, _currentBitmap.Height, GraphicsUnit.Pixel, imgAttributes);
  }
  _currentBitmap.Dispose();
  _currentBitmap = bmap;
}

另外,这里有一些进一步优化的提示:

  • 停止使用.Clone()。我看过代码,它到处都使用.Clone()。除非真的有必要,否则不要克隆对象。在图像处理中,您需要大量内存来存储大型图像文件。您需要在原地进行尽可能多的处理。
  • 您可以在方法之间传递Bitmap 对象by reference。您可以通过这种方式提高性能并降低内存成本。
  • 在处理 Graphics 对象时始终使用 using 块。
  • 当您确定不再需要 Bitmap 对象时,请在 .Dispose() 上调用它们

【讨论】:

  • 另外,你需要学习如何accept answers (link)。如果您找到适合您的答案,请点击旁边的复选框。
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 2010-12-21
相关资源
最近更新 更多