Reputation: 2093
I have this piece of Code ("ruta1" and "ruta2" are strings containing the path to different images):
Bitmap pic;
Bitmap b = new Bitmap(SomeWidth, SomeHeight);
g = Graphics.FromImage(b);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);
b.Save(ruta2, ImageFormat.Jpeg);
g.Dispose();
b.Dispose();
b = new Bitmap(OtherWidth, OtherHeight);
pic = new Bitmap(ruta2);
g = Graphics.FromImage(b);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);
g.DrawImage(pic, 0, 0, pic.Height, pic.Width);
pic.Dispose();
b.Save(ruta2, ImageFormat.Jpeg);
g.Dispose();
b.Dispose();
pic = new Bitmap(ruta1);
b = new Bitmap(AnotherWidth, AnotherHeight);
g = Graphics.FromImage(b);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);
int k = 1;
// I just draw the "pic" in a pattern on "b"
for (h = 0; h <= b.Height; h += pic.Height)
for (w = 0; w <= b.Width; w += pic.Width)
g.DrawImage(pic, w, h, k * pic.Width, k * pic.Height);
pic.Dispose();
GC.Collect(); // If I comment this line, I get a "generic GDI+ Error" Exception
b.Save(ruta1, ImageFormat.Jpeg);
g.Dispose();
b.Dispose();
It doesn't matter if I set pic = null after disposing it, if I don't call the Garbage Collector, I got a "Generic GDI+ Error" exception. Only when I call the Garbage Collector, my program goes ok, all times.
Can somebody explain this behavior? Does it depend on the .Net framework version? I'm using Visual C# Express 2008, with .Net framework 3.5
Upvotes: 0
Views: 528
Reputation: 1513
First, it would be nice if you were using the "using
" keyword to scope the use of your disposable objects (like Bitmap
and Graphics
), instead of calling Dispose()
manually on each. Using "using
" is better for lots of reasons like cleaning up stuff when an exception is thrown, but it also greatly helps for code readability.
Second, GDI brushes are also IDisposable
objects, so you shouldn't create-and-forget them. Do this instead:
using (var brush = new SolidBrush(Color.White))
{
g.FillRectangle(brush, 0, 0, width, height)
}
...or better yet, create your brushes at the start of your application, and hang on to them until the end (but don't forget to dispose of them too). IIRC, creating/disposing brushes impacts performance quite a lot if done frequently.
Third, I believe your bug is in the 2nd section:
If you refactor that 2nd section like this, it should work:
using (var b = new Bitmap(OtherWidth, OtherHeight))
using (var g = Graphics.FromImage(b))
{
using (var brush = new SolidBrush(Color.Red))
{
g.FillRectangle(brush, 0, 0, b.Width, b.Height);
}
using (var pic = new Bitmap(ruta2))
{
g.DrawImage(pic, 0, 0, pic.Height, pic.Width);
}
b.Save(ruta2, ImageFormat.Jpeg);
}
Upvotes: 1