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.