Доброго времени суток!
Необходимо загружать и выгружать данные из Image в бинарные данные, но не понимаю как. Ранее использовал binding к ресурсам или физическому файлу на диске.
Что я делал (код писал по памяти, потому могут быть опечатки или некоторые не точности)?
Создал окно, в которое поместил Image Source="{Binding myImage, converter={x:static StringToBitmapImageConverter}}" Как видно в свойстве myImage расположен string в формате base64 (данных загружаются из XML) и при помощи конвертера я их привожу в формат класса BitmapImage
Конвертер, если получает пустую строку, или не валидные данные, загружает из ресурсов значок по умолчанию.
При клике по картинке, открывается диалог выбора файла, откуда я считываю его бинарное представление и перевожу его в формат string Base64
После открытия файла - я не вижу картинку (она не отображается). Однако картинка по умолчанию загружается корректно.
Не могу понять в чем проблема.
Попробую привести пример кода, связанного с проблемным местом (как я думаю)
Конвертер
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string && targetType != null && targetType.Equals(typeof(ImageSource)))
// здесь я экспериментировал с проверкой типа, по отладке понял, что от окна приходит ImageSource
{
var bitmap = new BitmapImage();
try
{
var buffer = System.Convert.FromBase64String(value as string);
using (var ms = new MemoryStream())
{
// Здесь загрузка проходит, но изображение не появляется на экране
ms.Write(buffer, 0, buffer.Length);
ms.Seek(0, SeekOrigin.Begin);
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
bitmap.CacheOption = BitmapCacheOption.Default;
bitmap.EndInit();
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
return bitmap;
}
return GetDefaultBitmapImage(new Uri("pack://application:,,,/Money;Component/Ribbon/Coins/blue.png"));
}
private object GetDefaultBitmapImage(Uri uri)
{
// Здесь загрузка проходит корректно
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = uri;
bitmap.EndInit();
return bitmap;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is BitmapSource && targetType != null && targetType.Equals(typeof(string)))
{
var bitmap = value as BitmapImage;
if (bitmap != null && bitmap.StreamSource.CanRead)
{
byte[] buffer = new byte[bitmap.StreamSource.Length];
var count = bitmap.StreamSource.Read(buffer, 0, buffer.Length);
if (count == buffer.Length)
{
return System.Convert.ToBase64String(buffer, Base64FormattingOptions.InsertLineBreaks);
}
}
}
return string.Empty;
}
Описание класса к которому идет привязка
public class CoinViewModel : Vm
{
private Guid _ID;
public Guid ID
{
get => _ID;
set => Set(ref _ID, value, nameof(ID));
}
private string _Front;
public string Front
{
get => _Front;
set => Set(ref _Front, value, nameof(Front));
}
private string _Back;
public string Back
{
get => _Back;
set => Set(ref _Back, value, nameof(Back));
}
public static explicit operator CoinDataView(CoinViewModel vm)
{
return new CoinDataView()
{
ID = vm.ID,
Name = vm.Name,
Count = vm.Count,
SeriaID = vm.SeriaID,
Back = vm.Back,
Front = vm.Front
};
}
}
ну и собственно говоря, так происходит привязка
Ответ
Ваша ошибка в том, что вы освобождаете поток с данными, который использует BitmapImage, этого не надо делать — уберите using и напишите просто:
bitmap.StreamSource = new MemoryStream(buffer);
Комментариев нет:
Отправить комментарий