WPF BitmapImage 内存使用量

4
我正在尝试将一个图像的字节数组转换为BitmapImage以绑定到一个按钮。
public static BitmapImage GetBitmapImageFromByteArray(byte[] p_Image)
    {
        try
        {
            BitmapImage bmpImage;
            if (p_Image != null)
            {
                using (MemoryStream msStream = new MemoryStream(p_Image))
                {
                    msStream.Position = 0;
                    bmpImage = GetBitmapImageFromStream(msStream);
                    //msStream.Close();
                    return bmpImage;
                }
            }
        }
        catch
        {
        }
        return null;
    }

GetBitmapImageFromStream大致如下:

public static BitmapImage GetBitmapImageFromStream(MemoryStream msImage)
    {
        try
        {
            if (msImage == null) return null;
                BitmapImage bmpImg = new BitmapImage();
                msImage.Position = 0;
                bmpImg.BeginInit();
                bmpImg.CacheOption = BitmapCacheOption.OnLoad;
                bmpImg.StreamSource = msImage;
                bmpImg.EndInit();
                return bmpImg;

        }
        catch
        {
            return null;
        }
    }
在 bmpImg.EndInit() 的时候,内存出现了巨大的峰值。我的界面上有很多按钮,这是造成问题的原因。为什么会发生这种情况,我该如何解决或者恢复内存? 谢谢。

1
虽然它不能解决你的问题,但在 GetBitmapImageFromStream 函数中,你创建了一个“包装器”流,在 using 语句中没有被引用。 - Ben
2个回答

1
帮助中可以猜测它是创建一个缓存副本,可能还会创建一个缩小后用于按钮的副本。而且,由于GC不会清除复制到流中的所有数据,内存中会存在多个副本。

本:经过一些研究,我找到了你上面提到的问题,但是还在努力解决中。 - user296623
你能解释一下你的使用模式吗?你在哪里使用这些图片,有多少张图片,它们的尺寸是多少?如果你使用了很多需要经常查看或引用的图片,那么我认为你无法避免大量的内存使用,特别是如果你使用大型图片的话。 - Ben
每个图像大小约为45KB。我有30个自定义按钮,每个按钮显示4张图片。因此,总共有120张图片,可以占用高达6-7 MB的内存(120 x 44K)。但是我的应用程序正在使用约1.2GB的内存,并且我遇到了内存不足异常。 - user296623
一定有某个bug,我最近为我们的艺术家编写了一个编辑器,它使用并显示更多的图像(100-200张大小约为100-300KB),但它没有使用超过250MB的内存。但我的图像是从磁盘加载的。也许你的字节数组中有一些引用阻止了GC进行收集?当你创建BitmapImage时,内存峰值有多大? - Ben
每张图片大约为5000KB。 - user296623
显示剩余2条评论

0

尝试限制图像高度。您可以将DecodePixelHeight属性设置为BitmapImage。这将花费一些时间来转换您的字节,但最大高度将受到限制,并且内存使用量将减少。

                var bmpImg = new BitmapImage();
                msImage.Position = 0;
                bmpImg.BeginInit();

                 bmpImg.DecodePixelHeight =containerHeight; 

                bmpImg.CacheOption = BitmapCacheOption.OnLoad;
                bmpImg.StreamSource = msImage;
                bmpImg.EndInit();
                return bmpImg;

顺便提一下,你可能会在那里遇到内存泄漏问题。 http://code.logos.com/blog/2008/04/memory_leak_with_bitmapimage_and_memorystream.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接