2010-09-29 129 views
3

我工作的WPF应用程序有多个画布和大量的按钮。用户可以加载图像来更改按钮背景。WPF BitmapImage内存问题

这是我在对象的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()之前获取宽度?

回答

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的私人内存)

+0

哇,它真的给我留下了深刻的印象 - 这不仅在内存使用方面,而且在性能方面也是如此。感谢您提供一个非常简单明了的答案 - 对于照片库文件浏览器来说,这仅仅解决了我遇到的一些问题! – tpartee 2016-06-24 00:53:43