I'm developing an application in C#, and I developed a library that does some stuff with Aforge
cameras. One of the points is to simply capture images of what is in front of the Web Cam and show it on a specific PictureBox
to do so:
camera.NewFrame += NewFrame;
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = new Bitmap(args.Frame);
args.Frame.Dispose();
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
newFrame = null;
}
What I do here, I get every frame and paint it into the PictureBox
.
My doubt is:
In some computers, this way of painting produces a really high memory leak. The camera configuration is: 640x480, and if it's higher, memory leak increases.
Computer configuration:
Intel i5: memory leak to 500Mb
Intel i7: NO memory leak.
Double coeur (not so powerful): Not so much memory leak.
EDIT:
public static void FromBitmapImage(this Image image, Bitmap bitmap)
{
BitmapImage bitmapImage = new BitmapImage();
using (MemoryStream memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, ImageFormat.Bmp);
memoryStream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
}
image.Source = bitmapImage;
bitmapImage = null;
}
I don't understand why I have memory leak in some computers and others not... Any suggestion please?
NOTE: That memory leaks only happen in Release mode on Visual Studio 2010, but not on debug.
NOTE2: I think the problem comes with the FromBimapImage
, because I tried a WindowsForms
application instead of a WPF
one and no memory leak...
AForge owns the bytes of the image, you should make your own deep copy. Passing the frame to the Bitmap constructor is not enough. If the framework is not able to properly dispose the bitmap because you have a reference to it, there's a leak.
Try with this:
private void NewFrame(object sender, NewFrameEventArgs args)
{
Bitmap newFrame = AForge.Imaging.Image.Clone(args.Frame);
PictureBox.FromBitmapImage(newFrame);
newFrame.Dispose();
}