删除WPF控件使用的图像

时间:2010-03-11 08:53:15

标签: c# wpf file-locking

我想将Image绑定到某种控件上,稍后将其删除。

path = @"c:\somePath\somePic.jpg"
FileInfo fi = new FileInfo(path);
Uri uri = new Uri(fi.FullName, UriKind.Absolute);
var img = new System.Windows.Controls.Image();
img.Source = new BitmapImage(uri);

现在在这段代码之后我想删除文件:

fi.Delete();

但由于现在正在使用图像,所以我不能这样做。 在代码片段1和2之间我可以做什么来释放它?

2 个答案:

答案 0 :(得分:11)

您可以使用MemoryStream但实际上会浪费内存,因为位图数据的两个独立副本保存在RAM中:当您加载MemoryStream时,您可以创建一个副本,并且当位图被解码时另一份副本。以这种方式使用MemoryStream的另一个问题是您绕过缓存。

执行此操作的最佳方法是使用BitmapCacheOptions.OnLoad直接从文件中读取:

path = @"c:\somePath\somePic.jpg"

var source = new BitmapImage();
source.BeginInit();
source.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
source.CacheOption = BitmapCacheOption.OnLoad;
source.EndInit();  // Required for full initialization to complete at this time

var img = new System.Windows.Controls.Image { Source = source };

此解决方案也很有效且简单。

注意:如果您确实想要绕过缓存,例如因为图像可能在磁盘上发生变化,您还应该设置CreateOption = BitmapCreateOption.IgnoreImageCache。但即使在这种情况下,该解决方案也优于MemoryStream解决方案,因为它不会在RAM中保留两个图像数据副本。

答案 1 :(得分:3)

在提供给imagesource之前将图像复制到MemoryStream 它应该看起来像这样

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.DecodePixelWidth = 30;
bi.StreamSource = byteStream;
bi.EndInit();

其中byteStream是MemoryStream中文件的副本

this也很有用