Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Загрузка изображения в Image из бинарных данных

#c_sharp #wpf #изображения #binding


Доброго времени суток!

Необходимо загружать и выгружать данные из 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
        };
    }
}


ну и собственно говоря, так происходит привязка




    


Ответы

Ответ 1



Ваша ошибка в том, что вы освобождаете поток с данными, который использует BitmapImage, этого не надо делать — уберите using и напишите просто: bitmap.StreamSource = new MemoryStream(buffer);

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

Отправить комментарий