内存泄漏而异步加载的BitmapSource图片 [英] Memory leak while asynchronously loading BitmapSource images

查看:250
本文介绍了内存泄漏而异步加载的BitmapSource图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我加载到我的WPF应用程序的列表框一个公平的几张图片。本来我是使用GDI来调整图像(原件占用太多的内存)。这是很好,除了他们正在约每400ms的形象。事实并非如此精细。因此,在寻找另一种解决方案中,我发现,使用TransformedBitmap(从继承的BitmapSource)的方法。这是伟大的,我想,我可以使用。但我现在越来越内存泄漏的地方...

我加载使用异步一个BackgroundWorker像这样的图片:

 的BitmapSource BS = ImageUtils.ResizeBitmapSource(ImageUtils.GetImageSource(photo.FullName));
                //的BitmapSource BS = ImageUtils.GetImageSource(photo.FullName);
                bs.Freeze();                this.dispatcher.Invoke(新动作(()=> {photo.Source = BS;}));

GetImageSource只是获取从路径的位图,然后转换成的BitmapSource。

下面是ResizeBitmapSource的code片断:

  const int的thumbnailSize = 200;
        INT宽度;
        INT高度;        如果(bs.Width> bs.Height)
        {
            宽度= thumbnailSize;
            身高=(INT)(bs.Height * thumbnailSize / bs.Width);
        }
        其他
        {
            高度= thumbnailSize;
            宽度=(INT)(bs.Width * thumbnailSize / bs.Height);
        }        的BitmapSource tbBitmap =新TransformedBitmap(BS,
                                                           新ScaleTransform(宽/ bs.Width,
                                                                              高度/ bs.Height,0,0));        返回tbBitmap;

这code基本上是从code:
http://rongchaua.net/blog/c-wpf-fast-image-调整/

任何想法可能会导致泄漏?

编辑:
这里的code代表GetImageSource,按要求

 使用(VAR流=新的FileStream(路径,FileMode.Open,FileAccess.Read))
            {
                使用(VAR BMP = Image.FromStream(流,假的,假的))
                {
                    //使用WPF来调整
                    VAR的BitmapSource = ConvertBitmapToBitmapSource(BMP);
                    的BitmapSource = ResizeBitmapSource(的BitmapSource);
                    返回的BitmapSource;
                }
            }


解决方案

我觉得TransformedBitmap你误会了是如何工作的。它保持到对源位图的参考,并把它转换在存储器中。也许你可以带code中的位图转换成一个内存流,读它的右后卫了。我不知道有多快,这将是的,但你不会再举行到全尺寸的位图。

我发现返回的WriteableBitmap的与TransformedBitmap这博客文章作为源。该WriteableBitmap的将像素数据复制到在初始化存储器缓冲器,所以它实际上并不持有向TransformedBitmap,或全尺寸图像的参考

I have a fair few images that I'm loading into a ListBox in my WPF application. Originally I was using GDI to resize the images (the originals take up far too much memory). That was fine, except they were taking about 400ms per image. Not so fine. So in search of another solution I found a method that uses TransformedBitmap (which inherits from BitmapSource). That's great, I thought, I can use that. Except I'm now getting memory leaks somewhere...

I'm loading the images asynchronously using a BackgroundWorker like so:

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 just gets the Bitmap from the path and then converts to BitmapSource.

Here's the code snippet for 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;

That code is essentially the code from: http://rongchaua.net/blog/c-wpf-fast-image-resize/

Any ideas what could be causing the leak?

edit: Here's the code for GetImageSource, as requested

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;
                }
            }

解决方案

I think you misunderstood how the TransformedBitmap works. It holds onto a reference to the source bitmap, and transforms it in memory. Maybe you could encode the transformed bitmap into a memory stream, and read it right back out. I'm not sure how fast this would be, but you wouldn't then be holding on to the full sized bitmap.

I found this blog post that returned a WriteableBitmap with the TransformedBitmap as the source. The WriteableBitmap will copy the pixel data to a memory buffer in the initializer, so it doesn't actually hold on to a reference to the TransformedBitmap, or the full sized image.

这篇关于内存泄漏而异步加载的BitmapSource图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆