c# – Loading an image into an Image from binary data

Question:

Good day!

It is necessary to load and unload data from Image into binary data, but I don’t understand how. Previously used to bind to resources or a physical file on disk.

What did I do (the code was written from memory, so there may be typos or some inaccuracies)?

  1. I created a window in which I placed Image Source="{Binding myImage, converter={x:static StringToBitmapImageConverter}}" As you can see, in the myImage property there is a string in base64 format (the data is loaded from XML) and with the help of a converter I bring them to the class format BitmapImage
  2. The converter, if it receives an empty string, or not valid data, loads the default icon from the resources.
  3. When you click on the picture, a file selection dialog opens, from where I read its binary representation and convert it to string Base64 format
  4. After opening the file – I do not see the picture (it is not displayed). However, the default image is loaded correctly.

I can't figure out what the problem is.

I will try to give an example of code related to the problematic place (as I think)

Converter

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;
}

Description of the class to which the binding is going

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
        };
    }
}

well, actually, this is how the binding happens

<Image Grid.Column="0" MouseLeftButtonDown="Image_Front_MouseLeftButtonDown" Source="{Binding Front, Converter={StaticResource StringToBitmapImageConverter}}"></Image>
<Image Grid.Column="1" MouseLeftButtonDown="Image_Back_MouseLeftButtonDown" Source="{Binding Back, Converter={StaticResource StringToBitmapImageConverter}}"></Image>

Answer:

Your mistake is that you are freeing the data stream that uses the BitmapImage , you don't have to do this – remove the using and just write:

bitmap.StreamSource = new MemoryStream(buffer);
Scroll to Top