0

我在 WPF 窗口中有一个图像控件,它的 xmls 如下:

  <Image Source="{Binding Path=ImageUrl,Converter={StaticResource ImageSourceConverter}}"
        Height="150" HorizontalAlignment="Left" Margin="100,15,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="200" />

在运行时,我通过更改有界属性的值来更改 Image 的来源。此代码在正常情况下工作正常。只有在断开互联网连接后才会出现问题。如果下载图像时断开连接,则不会显示图像。没关系。但是当互联网恢复并且图像源更改为另一个图像 url 时,图像不会被下载。ImageConverter 甚至没有被调用。在此之后,无法在控件中显示图像。图像控制卡住。

public class ImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string url;
        try
        {
            if (value is string)
                url = (string)value;
            else
                url = ((Uri)value).AbsolutePath;
        }
        catch (Exception)
        {

            url = string.Empty;
            return value;
        }

        BitmapImage src = new BitmapImage();
        if (targetType == typeof(ImageSource))
        {
            if (value is string)
            {
                string str = (string)value;



                src.BeginInit();
                src.CacheOption = BitmapCacheOption.OnLoad;
                src.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                src.UriSource = new Uri(str, UriKind.RelativeOrAbsolute);
                src.EndInit();
                return src;

            }
            else if (value is Uri)
            {
                Uri uri = (Uri)value;
                return new BitmapImage(uri);
            }
        }
        return value;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

任何帮助将不胜感激。

4

2 回答 2

0

在关于内存泄漏的文章中讨论了使用下载的 BitmapImage 作为图像源引起的泄漏[7]:

引用:“触发此泄漏是因为 WPF 没有删除对在 Web 下载期间使用并导致泄漏的某些对象(例如 LateBoundBitmapDecoder、BitmapFrameDecode 等)的内部引用。

仅当您从 Internet 下载图像时才会发生这种泄漏。(例如,当您从本地计算机加载图像时它不会出现)"

...

修复/解决方法

解决方法是考虑先以其他方式将 BitmapImage 下载到临时文件夹或内存中,然后使用本地 BitmapImage 。(请参阅 WebClient.DownloadFile 和 WebClient.DownloadData API)

也许你会接近。

于 2013-06-07T20:31:17.443 回答
0

我通过首先下载图像来解决问题,如果成功,则仅将其分配给图像控件。把它贴在这里以防万一有人需要它。

private bool ValidImage(string url, out BitmapImage image)
    {
        try
        {
            System.Net.WebRequest request = System.Net.WebRequest.Create(url);
            System.Net.WebResponse response = request.GetResponse();
            System.IO.Stream responseStream = response.GetResponseStream();
            Bitmap bitmap = new Bitmap();
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Png);

                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
                // Force the bitmap to load right now so we can dispose the stream.
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                image = result;
            }

        }
        catch (Exception ex)
        {
            logger.Error(ex, "error downlading image");
            image = null;
            return false;
        }

        return true;
    }
于 2013-06-08T08:38:23.503 回答