WPF位图图像内存问题

3

我正在开发一个WPF应用程序,它有多个画布和大量按钮。用户可以加载图像以更改按钮的背景。

这是我加载图像到BitmapImage对象中的代码

bmp = new BitmapImage();
bmp.BeginInit();
bmp.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.UriSource = new Uri(relativeUri, UriKind.Relative);
bmp.EndInit();

在 EndInit() 期间,应用程序的内存会急剧增长。

有一件事可以让情况变得更好(但并不能真正解决问题),那就是添加:

bmp.DecodePixelWidth = 1024;

1024是我画布的最大尺寸。但我应该只针对宽度大于1024的图像进行此操作-那么如何在EndInit()之前获取宽度?

1个回答

5
通过将图像加载到BitmapFrame中,我认为你可以仅读取元数据。
private Size GetImageSize(Uri image)
{
    var frame = BitmapFrame.Create(image);
    // You could also look at the .Width and .Height of the frame which 
    // is in 1/96th's of an inch instead of pixels
    return new Size(frame.PixelWidth, frame.PixelHeight);
}

当加载BitmapSource时,您可以执行以下操作:

var img = new Uri(ImagePath);
var size = GetImageSize(img);
var source = new BitmapImage();
source.BeginInit();
if (size.Width > 1024)
    source.DecodePixelWidth = 1024;
source.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
source.CacheOption = BitmapCacheOption.OnLoad;
source.UriSource = new Uri(ImagePath);
source.EndInit();
myImageControl.Source = source;

我测试了几次并查看了任务管理器中的内存消耗,差异非常大(在一张10MP的照片上,通过以1024像素宽度加载而不是4272像素宽度,我节省了近40MB的私有内存)


哇,这真的很令人印象深刻,不仅在内存使用方面,而且在性能方面也有很大的改善。感谢您提供如此简单明了的答案 - 对于一个照片库文件浏览器,这个解决方案已经解决了我遇到的许多问题! - tpartee

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