如果我正在使用.Dispose();为什么我继续记忆力不足

时间:2010-10-02 03:11:42

标签: c# .net image-manipulation

我正在使用C#3.5 .NET和Windows Form 我有这个代码来管理图像的亮度,它在trackBar ValueChanges

时激活
public void brightnesstrackBar1_ValueChanged(object sender, EventArgs e) 
{
       domainUpDownB.Text = ((int)brightnessTrackBar.Value).ToString();
        B = ((int)brightnessTrackBar.Value);
        pictureBox2.Image = AdjustBrightness(foto, B);
        foto1 = (Bitmap)pictureBox2.Image;
    }


 public static Bitmap AdjustBrightness(Bitmap Image, int Value)
    {

        Bitmap TempBitmap = Image;
        float FinalValue = (float)Value / 255.0f;
        Bitmap NewBitmap  = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);
        Graphics NewGraphics = Graphics.FromImage(NewBitmap);

        float[][] FloatColorMatrix ={
                                        new float[] {1, 0, 0, 0, 0},
                                        new float[] {0, 1, 0, 0, 0},
                                        new float[] {0, 0, 1, 0, 0},
                                        new float[] {0, 0, 0, 1, 0},
                                        new float[] {FinalValue, FinalValue, FinalValue, 1, 1
                                    }
            };

        ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix);
        ImageAttributes Attributes = new ImageAttributes();
        Attributes.SetColorMatrix(NewColorMatrix);
        NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, Attributes);
        Attributes.Dispose(); 
        NewGraphics.Dispose(); 
        return NewBitmap;
    }

确定这是问题...如果我加载一个大图像(例如像素) 并且在几次移动后开始移动trackBar它将显示着名的“内存不足执行没有被删除”并且错误指向此行

  NewGraphics.DrawImage(TempBitmap, 
        new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, 
        TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, 
        Attributes);
你们都可以看到我正在处理你们。我尝试使用

 this.SetStyle(ControlStyles.OptimizedDoubleBuffer | 
          ControlStyles.AllPaintingInWmPaint | 
          ControlStyles.UserPaint, true);

并将双缓冲区设置为true但是没有什么能解决问题,我可以使用程序将使用的内存量,或者有另一种方法来解决这个问题。

4 个答案:

答案 0 :(得分:6)

您(显示)为轨道栏值的每次更新生成一个新图像'NewBitmap',但您永远不会Dispose()此图像。

尝试在pictureBox2.Image = AdjustBrightness(foto, B);

之前插入以下内容
Image oldImg = pictureBox2.Image;
if (oldImg != null)
{
    oldImg.Dispose();
}

答案 1 :(得分:2)

您正在泄漏您的位图。他们也需要处理。基本上,只需查看您正在使用的所有对象。如果他们实施IDisposable,他们必须被处置。

public void brightnesstrackBar1_ValueChanged(object sender, EventArgs e) {
        domainUpDownB.Text = ((int)brightnessTrackBar.Value).ToString();
        B = ((int)brightnessTrackBar.Value);
// TODO: Need to dispose of return value from AdjustBrightness somehow
// I need more code to figure out where
        pictureBox2.Image = AdjustBrightness(foto, B);
        foto1 = (Bitmap)pictureBox2.Image;
    }

// Note: Returns a Bitmap that must be Disposed public static Bitmap AdjustBrightness(Bitmap Image, int Value) { int width, height; float FinalValue = (float)Value / 255.0f; using (Bitmap TempBitmap = Image) { width = TempBitmap.Width; height = TempBitmap.Height; } Bitmap NewBitmap = new System.Drawing.Bitmap(width, height); using (Graphics NewGraphics = Graphics.FromImage(NewBitmap)) { float[][] FloatColorMatrix ={ new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {FinalValue, FinalValue, FinalValue, 1, 1} };
ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix); using (ImageAttributes Attributes = new ImageAttributes()) { Attributes.SetColorMatrix(NewColorMatrix); NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, Attributes); } } return NewBitmap; }

答案 2 :(得分:2)

除了处理IDisposable之外的任何内容(正如Kevin和Aaron已经建议的那样),请确保您正在计时,以便引用任何处置后的对象已被处置,因为他们可能不处于无法/无效状态。 (更多信息,例如http://msdn.microsoft.com/en-us/library/8th8381z.aspx。)

我也知道,了解fotofoto1变量是什么可能会有所帮助。

答案 3 :(得分:0)

好的,到目前为止,我不同意大多数答案(所以我可能会被证明是错的,但无论如何都要这样做。)

<。>当.Net无法再获取“托管”内存时,会发生OutOfMemoryException。在.Net 1.0中,默认限制大约是600 Mb,现在不知道它是什么。 “托管”内存与IDisposable无关,即非托管资源(句柄,非托管内存)等。耗尽非托管内存可能导致托管内存耗尽,但更可能导致COM或Win32 API错误

现在说,处理IDisposable对象是必不可少的。考虑使用“使用”构造。查找一下,这是“使用”关键字的三种用法之一。

我的猜测是,其中一些对象也有一个很大的“托管内存”占用空间,并且你创建它们太快,垃圾收集器无法查看。我的建议是你考虑创建这些对象一次然后重复使用它们。

实际上早在早期的.Net中,真正的大型托管内存对象从未被清理过,因为您需要重用它们。从那时起,我认为他们改变了这个决定。

祝你好运。

相关问题