我正在使用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但是没有什么能解决问题,我可以使用程序将使用的内存量,或者有另一种方法来解决这个问题。
答案 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。)
我也知道,了解foto
和foto1
变量是什么可能会有所帮助。
答案 3 :(得分:0)
好的,到目前为止,我不同意大多数答案(所以我可能会被证明是错的,但无论如何都要这样做。)
<。>当.Net无法再获取“托管”内存时,会发生OutOfMemoryException。在.Net 1.0中,默认限制大约是600 Mb,现在不知道它是什么。 “托管”内存与IDisposable无关,即非托管资源(句柄,非托管内存)等。耗尽非托管内存可能导致托管内存耗尽,但更可能导致COM或Win32 API错误现在说,处理IDisposable对象是必不可少的。考虑使用“使用”构造。查找一下,这是“使用”关键字的三种用法之一。
我的猜测是,其中一些对象也有一个很大的“托管内存”占用空间,并且你创建它们太快,垃圾收集器无法查看。我的建议是你考虑创建这些对象一次然后重复使用它们。
实际上早在早期的.Net中,真正的大型托管内存对象从未被清理过,因为您需要重用它们。从那时起,我认为他们改变了这个决定。
祝你好运。