我在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();
}
}
任何帮助都将受到高度赞赏。
答案 0 :(得分:0)
关于内存泄漏的article讨论了使用下载的BitmapImage作为图像源引起的泄漏[7]:
引用:“此漏洞被触发,因为WPF不会删除在Web下载期间使用的某些对象(如LateBoundBitmapDecoder,BitmapFrameDecode等)的内部引用,并导致泄漏。
只有从互联网下载图像时才会发生此泄漏。 (例如,从本地计算机加载图像时不会出现)“
...
修复/解决方法
解决方法是考虑首先以其他方式将BitmapImage下载到临时文件夹或内存,然后使用本地BitmapImage。 (参见WebClient.DownloadFile&amp; WebClient.DownloadData API)
也许你会接近。
答案 1 :(得分:0)
我首先通过下载图像解决了问题,如果成功,则仅将其分配给Image控件。如果有人需要,请在此处发布。
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;
}