WPF:使用ValueConverter为ImageSource创建BitmapImage的内存含义 [英] WPF: Memory implications of using ValueConverter to create BitmapImage for ImageSource
问题描述
我在使用图像时遇到问题,并提供了一个右键单击上下文菜单以删除图像.
I had an issue with using Images and provide a right-click context menu for deleting the Image.
最初,我绑定了绝对文件路径:
Originally I was binding the absolute file path:
<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
.经过大量研究,我发现了必要的代码更改.
I was getting an error, The process cannot access the file 'X' because it is being used by another process
. After a lot of research, I figured out the necessary code change.
我使用了这个Stackoverflow答案:删除另一个进程正在使用的文件,并将代码放入ValueConverter
.
I used this Stackoverflow answer: Delete a file being used by another process and put the code into a 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();
}
}
-
我所关心的是内存使用情况.当我将图像添加到我的 容器,我看到内存增加了.但是,当我删除图片时, 并且基础文件被删除,我看不到任何内存 释放.
The concern I have is memory usage. When I add Images to my Container, I see memory increase. However, when I delete Images, and the underlying file is deleted, I do not see any memory being freed up.
我也一直认为位图是一个效率很低的文件
格式,因为它们是未压缩的,并且与
JPEG或PNG文件.是个
System.Windows.Media.Imaging.BitmapSource
类实际创建
从我的PNG中提取出未压缩的图像?
I've also always thought of Bitmaps as a very inefficient file
format, since they are uncompressed, and tend to be HUGE compared to
a JPEG or PNG file. Is the
System.Windows.Media.Imaging.BitmapSource
class actually creating
an uncompressed image out of my PNG?
非常感谢!
菲利普
推荐答案
WPF caches up to 300 ImageSource
objects (using weak references) when you load an image from a URI. To avoid this, set the BitmapCreateOptions.IgnoreImageCache
option or use a FileStream
to load the image instead.
请注意,这可能会对应用程序的性能产生不利影响,尤其是在您要在虚拟化的ListBox
中滚动和加载图像的情况下.但是,如果要加载非常大的图像,则可能要避免使用它.
Note that this could have an adverse effect on your app's performance, especially in a situation where you're scrolling and loading images in a virtualized ListBox
. But if you're loading really large images, you might want to avoid it.
在转换器中使用以下代码(另请注意添加的image.Freeze
调用,该调用通过使对象为只读且与线程无关来提高性能):
Use the following code in your converter (note also the added image.Freeze
call, which improves performance by making the object read-only and thread-agnostic):
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = fs;
image.EndInit();
image.Freeze();
return image;
}
另一种可能的性能优化是将DecodePixelWidth
设置为缩小图像.
Another possible performance optimization is to set DecodePixelWidth
to downscale the image.
关于格式方面的问题-位图是基于像素的图像(与基于矢量的图像相比)的通用名称.您提到的文件格式(PNG,JPEG)也是位图,它们只是经过编码(可能经过了压缩). BitmapImage
类使用WIC对其进行解码,以便可以在屏幕上呈现它们.
Regarding your concern about formats -- bitmap is a general name for pixel-based images (in contrast to vector-based images). The file formats you mentioned (PNG, JPEG) are bitmaps as well, they're just encoded (possibly with some compression). The BitmapImage
class uses WIC to decode them so they can be rendered on the screen.
这篇关于WPF:使用ValueConverter为ImageSource创建BitmapImage的内存含义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!