But today, I've been working on a memory leak... These bugs are really annoying to work on, but anyhow here is what I found out:
The problem is that the sample code and samples I've found on the internet for converting Bitmap to BitmapSource. The code usually looks something like this:
image1.Source = Imaging.CreateBitmapSourceFromHBitmap(
new System.Drawing.Bitmap(args.Image).GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
This works fine, but it also creates a HBitmap in unmanaged memory that it doesn't free.
A better way to solve this is to store the HBitmap in a variable and call DeleteObject on it. DeleteObject is a function from gdi32.dll:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
Here is the code I ended up with in our production code:
private void TwainOnTransferImage(Object sender, TransferImageEventArgs e) {
if (e.Image != null) {
var bmp = new System.Drawing.Bitmap(e.Image);
IntPtr hBitmap = bmp.GetHbitmap();
image1.BeginInit();
image1.Source = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
image1.EndInit();
image1.Source.Freeze();
DeleteObject(hBitmap);
bmp.Dispose();
e.Image.Dispose();
}
}