异步加载BitmapSource映像时内存泄漏

我有一些我正在加载到WPF应用程序中的ListBox中的图像。 最初我使用GDI来调整图像大小(原件占用的内存太多)。 这很好,除了他们每张图片大约需要400毫秒。 不太好。 因此,在寻找另一种解决方案时,我发现了一种使用TransformedBitmap(inheritance自BitmapSource)的方法。 那很好,我想,我可以用它。 除了我现在正在某处发生内存泄漏……

我正在使用BackgroundWorker异步加载图像,如下所示:

BitmapSource bs = ImageUtils.ResizeBitmapSource(ImageUtils.GetImageSource(photo.FullName)); //BitmapSource bs = ImageUtils.GetImageSource(photo.FullName); bs.Freeze(); this.dispatcher.Invoke(new Action(() => { photo.Source = bs; })); 

GetImageSource只从路径获取Bitmap,然后转换为BitmapSource。

这是ResizeBitmapSource的代码片段:

 const int thumbnailSize = 200; int width; int height; if (bs.Width > bs.Height) { width = thumbnailSize; height = (int)(bs.Height * thumbnailSize / bs.Width); } else { height = thumbnailSize; width = (int)(bs.Width * thumbnailSize / bs.Height); } BitmapSource tbBitmap = new TransformedBitmap(bs, new ScaleTransform(width / bs.Width, height / bs.Height, 0, 0)); return tbBitmap; 

该代码基本上来自以下代码: http : //rongchaua.net/blog/c-wpf-fast-image-resize/

什么可能导致泄漏的想法?

编辑:这是GetImageSource的代码,按要求

 using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (var bmp = Image.FromStream(stream, false, false)) { // Use WPF to resize var bitmapSource = ConvertBitmapToBitmapSource(bmp); bitmapSource = ResizeBitmapSource(bitmapSource); return bitmapSource; } } 

我想你误解了TransformedBitmap是如何工作的。 它保留对源位图的引用,并将其转换为内存。 也许你可以将转换后的位图编码成一个内存流,然后立即将其读出来。 我不确定这会有多快,但你不会坚持使用全尺寸的位图。

我发现这篇博客post返回了一个带有TransformedBitmap作为源的WriteableBitmap。 WriteableBitmap会将像素数据复制到初始化程序中的内存缓冲区,因此它实际上不会保留对TransformedBitmap或全尺寸图像的引用。

猜测一下,从查看代码开始,您可能需要处理调用ImageUtils.GetImageSource(photo.FullName)返回的位图。

我还在博客上指出,作者已经添加了一个关于插入using语句以防止内存泄漏的更新(3月11日)。