【发布时间】:2014-05-18 20:39:30
【问题描述】:
我在使用图像时遇到了问题,我提供了一个右键单击上下文菜单来删除图像。
原来我是绑定绝对文件路径的:
<Image Source="{Binding Path=ImageFileName} .../>
其中ImageFileName 类似于C:\myapp\images\001.png。
我遇到了一个错误,The process cannot access the file 'X' because it is being used by another process。经过大量研究,我想出了必要的代码更改。
我使用了这个 Stackoverflow 答案:Delete a file being used by another process 并将代码放入 ValueConverter。
XAML:
<Image Source="{Binding Path=ImageFileName,
Converter={StaticResource pathToImageConverter}}" ...>
值转换器:
public class PathToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
String fileName = value as String;
if (fileName != null)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(fileName);
image.EndInit();
return image;
}
return new BitmapImage();
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我担心的是内存使用情况。当我将图像添加到我的 容器,我看到内存增加了。但是,当我删除图像时, 并且底层文件被删除,我没有看到任何内存 释放。
我也一直认为位图是一个非常低效的文件 格式,因为它们是未压缩的,并且与 JPEG 或 PNG 文件。是个
System.Windows.Media.Imaging.BitmapSource类实际创建 我的 PNG 中的未压缩图像?
提前非常感谢!
菲利普
【问题讨论】:
-
删除图像并不能保证内存会被释放。只要垃圾收集器认为合适,就会收集内存。通过手动调用 GC.Collect() 进行交叉检查并查看内存是否释放。
-
您是否考虑过在图像上使用 VirtualizingStackPanel 并指定 DecodePixel* 属性?
-
@Aybe 不,我没有,但我会调查这些。老实说,直到现在才听说过 VirtualizingStackPanel。
-
@Aybe 此处需要绑定转换器,以便能够在将图像文件加载到 BitmapImage 后立即删除它。这不适用于内置的(字符串到 ImageSource)类型转换器。
-
嗯,这很简单。下载并安装JetBrains dotPeek,加载 PresentationCore.dll,然后检查命名空间 System.Windows.Media 中 ImageSourceConverter 类中的 ConvertFrom 方法。