简体   繁体   中英

How do I display a resource property image in <Image>?

I'm trying to display an image I have saved as a resource under the properties category. This property however returns a byte[] which can't be displayed by <Image> since it can't convert it to ImageSource . The code looks like this:

public byte[] MyImage = Properties.ImageResources.MyImage

but plugging MyImage into

<Image Source="{x:Bind MyImage}"

gives me a conversion error as described above.

I've already tried converting the image to a bitmap to display this instead, but I got the very same error. I've read alot about something like

bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();

but then it tells me it can't resolve any of the BitmapImage Functions -> BeginInit, EndInit, StreamSource and CacheOption.

I've searched far and wide but they all end in this BeginInit() and EndInit() function which do not exist for me.

Do you have a UWP application? In WPF, when Binding is used, type conversion is performed. The ImageSource type provides conversion from the Stream, byte[], Uri and string types. You are using x:Bind. And x:Bind does no type conversion.
I'm not sure about UWP, but try replacing x:Bind with Binding.

You can get an ImageSource from an array of bytes like this:

    BitmapImage bitmap = new();
    using (MemoryStream stream = new(imageBytes))
    {
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.EndInit();
    }
    bitmap.Freeze();

Also, keep in mind that bindings require properties, not fields.

public byte[] MyImage {get;} = Properties.ImageResources.MyImage;

For WinUI it might be like this:

    var bitmapImage = new BitmapImage();

    using (var stream = new InMemoryRandomAccessStream())
    {
        using (var writer = new DataWriter(stream))
        {
            writer.WriteBytes(bytesArray);
            writer.Store().Wait();
            writer.Flush().Wait();
            writer.DetachStream();
        }

        stream.Seek(0);
        bitmapImage.SetSource(stream);
    }

I took as a basis the code from the topic: Convert byte[] to Windows.UI.Xaml.Media.Imaging.BitmapImage .
The topic shows an asynchronous solution. Here I tried to upgrade it to synchronous. I'm not sure if my code is correct because there are many types and methods in WinUI that I don't know about.

Thanks to the help of EldHasp I've found a way to make the images appear.

I have created a data binding converter class that implements the IValueConverter interface:

public class ByteArrayToBitmapImageConverter : IValueConverter
{
    public object? Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is not byte[])
        {
            return null;
        }

        using var ms = new InMemoryRandomAccessStream();
        using (var writer = new DataWriter(ms.GetOutputStreamAt(0)))
        {
            writer.WriteBytes((byte[])value);
            writer.StoreAsync().GetResults();
        }

        var image = new BitmapImage();
        image.SetSource(ms);
        return image;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException();
}

Or shorter:

public object Convert(
    object value, Type targetType, object parameter, string language)
{
    BitmapImage image = null;

    if (value is byte[] buffer)
    {
        using var ms = new MemoryStream(buffer);
        image = new BitmapImage();
        image.SetSource(ms.AsRandomAccessStream());
    }

    return image;
}

It would be used in XAML eg like shown below, when MyImage is a public property of the object in the DataContext of the Grid:

<Grid>
    <Grid.Resources>
        <local:ByteArrayToBitmapImageConverter x:Key="ImageConverter"/>
    </Grid.Resources>

    <Image Source="{Binding MyImage, Converter={StaticResource ImageConverter}}"/>
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM