【发布时间】:2010-03-11 19:48:36
【问题描述】:
我有一些图像要加载到我的 WPF 应用程序的 ListBox 中。最初我使用 GDI 来调整图像大小(原件占用太多内存)。这很好,除了他们每张图像需要大约 400 毫秒。不太好。因此,在寻找另一种解决方案时,我找到了一种使用 TransformedBitmap(继承自 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 的代码 sn-p:
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;
}
}
【问题讨论】:
-
您是如何诊断泄漏的?为什么你认为它在这段代码中,而不是在 GetImageSource() 中?
-
我在 WPF 控件中使用的 BitmapSource 已正确调整大小,但查看进程使用的内存,它使用的内存与全尺寸图像一样。因此,沿着这条线的某个地方,全尺寸的 BitmapSource 并没有被删除。编辑:因为 GetImageSource 并没有真正改变。如果我选择使用 GDI 调整大小,那很好。但是当我使用这个 TransformedBitmap 方法调整大小时,它不起作用。
-
你能不能尝试调用手动GC来查看内存是否被释放?如果不是,您很可能在某个地方有一个引用来保存内存。
-
你能把你的代码发给
ImageUtils.GetImageSource()吗?我怀疑那里发生了泄漏。 -
我已将代码添加到 GetImageSource。 ConvertBitmapToBitmapSource() 的代码仅使用 Imaging.CreateBitmapSourceFromHBBitmap()。我以为可能是这样,但我不仅在原版中使用了这种方法,而且还删除了 Hbitmap IntPtr...
标签: c# wpf image memory-leaks bitmap