删除WPF控件使用的图像

Pet*_*ter 5 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);
Run Code Online (Sandbox Code Playgroud)

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

fi.Delete();
Run Code Online (Sandbox Code Playgroud)

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

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

该解决方案也是高效且简单的.

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


Ars*_*yan 3

在提供给 imagesource 之前将图像复制到 MemoryStream 它应该如下所示

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.DecodePixelWidth = 30;
bi.StreamSource = byteStream;
bi.EndInit();
Run Code Online (Sandbox Code Playgroud)

其中 byteStream 是 MemoryStream 中文件的副本

也很有用

  • TX,它有效。对于后来的读者:我已将其复制到这样的内存流中: MemoryStream byteStream = new MemoryStream(File.ReadAllBytes(path)); (2认同)