WPF замороженное растровое изображение не отображается

#wpf #bitmapsource #freezable

#wpf #bitmapsource #замораживаемый

Вопрос:

Я использую viewmodel, привязанный к свойству изображения в пользовательском интерфейсе, а viewmodel содержит свойство ImageSource. Я установил это свойство, используя следующую функцию

     private BitmapImage GetImageFromUri(Uri urisource)
    {
        if (urisource == null)
            return null;

        var image = new BitmapImage();
        image.BeginInit();
        image.UriSource = urisource;
        image.EndInit();
        image.Freeze(); //commenting this shows the image if the routine is called from the proper thread.

        return image;
   }
  

По какой-то странной причине в следующем коде, когда я вызываю Freeze для своего растрового изображения, оно не отображается в главном окне.Я не получаю никаких исключений или сбоев. Кто-нибудь может мне помочь с этим?
Я устанавливаю свойство изображения асинхронно, поэтому мне нужно иметь возможность использовать созданное изображение, предполагая, что вызов GetImageFromUri был выполнен из потока, отличного от потока пользовательского интерфейса.

Ответ №1:

Попробуйте установить параметр CacheOption для BitmapImage перед его замораживанием. Посмотрите, работает ли это —

 var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = urisource;
image.EndInit();
image.Freeze();
  

Ответ №2:

Прежде чем заморозить его, вам необходимо полностью отобразить его.
Вы должны попытаться прослушать событие SourceUpdated и только после этого заморозить изображение.

Кстати, если вы когда-нибудь захотите изменить изображение после этого, вам придется его клонировать.

Комментарии:

1. Что вы подразумеваете под его отображением?

2. Визуализируется графически. Настройки источник не делает его визуализируемым, WPF сначала необходимо отобразить изображение. Похоже, вы замораживаете его до того, как WPF получит возможность это сделать.

Ответ №3:

ЕСЛИ я использую StreamSource , для меня достаточно:

 public static BitmapSource ToBitmap(this MemoryStream stream)
    {
        try
        {
            using (stream)
            {
                stream.Position = 0;
                var image = new BitmapImage();
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.StreamSource = stream;
                image.EndInit();
                image.Freeze();
                return image;
            }
        }
        catch (Exception)
        {
            return null;
        }
    }
  

Но если я использую UriSource , мне нужно:

 public static async Task<BitmapSource> ToBitmapAsync(this string sourceUri)
    {
        try
        {
            using (var client = new WebClient())
            using (var stream = await client.OpenReadTaskAsync(new Uri(sourceUri)))
            using (var ms = new MemoryStream())
            {
                stream.CopyTo(ms);
                return ms.ToBitmap();
            }
        }
        catch (Exception)
        {
            return null;
        }
    }
  

BitmapSource есть UriSource , но он работает после рендеринга xaml