|I have eventually found a "solution" to this problem.
Be prepared: that empirical solution makes no real sense, but this works...
Solution was to go through the following convertions:
- byte to Bitmap using GetConverter;
- Bitmap redrawn to a new Bitmap using GDI+ Graphics
- Bitmap to byte again using ImageConverter
- byte to ImageSource using the previously mentioned BitmapFromRaw Method.
Any attempt to simplify this code lead to the memory leak to come back.
No clue how this could be the way to get the GC do its job. Like in relativity, the shortest path is not always the straight one...
Here is the the extra code that works for me. It makes my eyes bleed and I'm not proud of it. So again, if anyone could get something cleaner working, please propose.
public static ImageSource? BitmapFromRawNoLeak(byte? imageData)
if (imageData == null) return null;
ImageSource? image = null;
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
using (Bitmap? bmp = (Bitmap?)tc.ConvertFrom(imageData))
if (bmp == null) return null;
using (Bitmap source = new Bitmap(bmp.Width, bmp.Height))
if (source == null) return null;
using (Graphics g = Graphics.FromImage(source))
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);
ImageConverter converter = new ImageConverter();
var vect = (byte)converter.ConvertTo(source, typeof(byte));
image = BitmapFromRaw(vect);