代码之家  ›  专栏  ›  技术社区  ›  Peter Booster

删除已由WPF控件使用的图像

  •  5
  • Peter Booster  · 技术社区  · 15 年前

    我想把一个图像绑定到某种控件上,稍后再删除它。

    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 回复  |  直到 7 年前
        1
  •  3
  •   Arsen Mkrtchyan    15 年前

    在将图像提供给ImageSource之前,将图像复制到MemoryStream 应该像这样

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

    其中bytestream是memorystream中文件的副本

    this 可以有用

        2
  •  11
  •   Zach Green    11 年前

    你可以用一个 MemoryStream 但这实际上浪费了内存,因为两个单独的位图数据副本保存在RAM中:当加载 内存流 您可以制作一个副本,当对位图进行解码时,会制作另一个副本。另一个使用问题 内存流 这样就可以绕过缓存。

    最好的方法是使用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 . 但即使在这种情况下,这个解决方案也比 内存流 解决方案,因为它不在RAM中保留图像数据的两个副本。

    推荐文章