views:

1159

answers:

1

I need draw an image pixel by pixel and display it inside a WPF. I am attempting to do this by using a System.Drawing.Bitmap then using CreateBitmapSourceFromHBitmap to create a BitmapSource for a WPF Image control. I have a memory leak somewhere because when the CreateBitmapSourceFromBitmap is called repeatedly the memory goes up and does not drop off until the application is ended. If I don't call CreateBitmapSourceFromBitmap there is no noticable change in memory usage.


            for (int i = 0; i < 100; i++)
            {
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(1000, 1000);
                var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
                    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                source = null;
                bmp.Dispose();
                bmp = null;
            }

What can I do to free the BitmapSource memory?

+4  A: 

MSDN says for Bitmap.GetHbitmap(): You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object. , so use the following code:

// at class level
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

// your code
using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(1000, 1000)) {
    IntPtr hBitmap = bmp.GetHbitmap();
    try {
        var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
    }
    finally {
        DeleteObject(hBitmap)
    }
}

I also replaced your Dispose() call by an using statement.

Julien Lebosquain
That works. There is a bit of residual memory held after the test, but the garbage collector picks it up. Thanks Julien.
Mr Bell