If I am using .Dispose(); why I continue having an Out of memory
I am using C# 3.5 .NET and Windows Form I have this code to manage the Brightness of an image, it activates when the 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[开发者_如何学Python][] 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;
}
OK this is the problem ... if I load a big image(as in pixels for example) and start moving the trackBar after a few moves it will show the famous "Out of memory exeption was unhanded" and the error points to this line
NewGraphics.DrawImage(TempBitmap,
new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0,
TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel,
Attributes);
as you all can see i am disposing. I try to use
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);
and set the double buffer to true But nothing fixes the problem can i incrise the amount of memory the program will use or there is another way to solve this problem.
You (appear) to generate a new image, 'NewBitmap'
, for every update of the trackbar's value, but you never Dispose() of this image.
Try inserting the following before pictureBox2.Image = AdjustBrightness(foto, B);
Image oldImg = pictureBox2.Image;
if (oldImg != null)
{
oldImg.Dispose();
}
You are leaking your Bitmaps. They need to be disposed too. Basically, just look at all the objects you are using. If they implement IDisposable, they must be disposed of.
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;
}
In addition to disposing anything that's IDisposable
(as Kevin and Aaron have already suggested), make sure that you're timing things so as to not reference any disposed objects after they've been disposed, as they may not be in a unable/invalid state. (More at, e.g., http://msdn.microsoft.com/en-us/library/8th8381z.aspx.)
It also occurs to me that it might be helpful to know what the foto
and foto1
variables are...
Ok, I'm going to disagree with most of the answers so far (so I'm probably going to be proven wrong but here goes anyway).
OutOfMemoryException occurs when .Net can not aquire any more "managed" memory. The default limit used to be around 600 Mb in .Net 1.0, no idea what it is these days. "managed" memory has nothing to do with IDisposable, that is for unmanaged resources (handles, unmanaged memory) etc. Running out of unmanaged memory might cause the managed memory to run out, but more likely it would cause a COM or Win32 API error.
Now that said, Disposing of IDisposable objects is essential. Consider using the "using" construct. Look it up, it's one of the three uses of "using" keyword.
My guess is that some of these objects aslo have a big "managed memory" footprint, and that you are creating them too fast for the garbage collector to get a look in. My recommendation is that you consider creating these objects once and then reuse them.
Actually back in early .Net really big managed memory objects never got cleaned up because you were expected to reuse them. Since then I think they changed this decision.
Best of luck.
精彩评论