WPF BitmapImage内存问题

mor*_*anu 3 memory wpf bitmapimage

我在一个WPF应用程序上工作,该应用程序有多个画布和许多按钮.用户可以加载图像以更改按钮背景.

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

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

并且在EndInit()应用程序的内存增长非常多.

让思考更好(但并没有真正解决问题)的一件事就是增加

bmp.DecodePixelWidth = 1024;
Run Code Online (Sandbox Code Playgroud)

1024 - 我的最大画布大小.但我应该只对宽度大于1024的图像执行此操作 - 那么如何在EndInit()之前获得宽度?

Isa*_*avo 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);
}
Run Code Online (Sandbox Code Playgroud)

然后在加载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;
Run Code Online (Sandbox Code Playgroud)

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