WPF:使用ValueConverter为ImageSource创建BitmapImage的内存含义 [英] WPF: Memory implications of using ValueConverter to create BitmapImage for ImageSource

查看:141
本文介绍了WPF:使用ValueConverter为ImageSource创建BitmapImage的内存含义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用图像时遇到问题,并提供了一个右键单击上下文菜单以删除图像.

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();
    }
}

  1. 我所关心的是内存使用情况.当我将图像添加到我的 容器,我看到内存增加了.但是,当我删除图片时, 并且基础文件被删除,我看不到任何内存 释放.

  1. 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最多缓存

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆