Reputation: 580
C# / Universal Windows Platform
I have an object that contains a property that contains an image as a base64 encoded string. How would I bind this string to an image on the front end? Currently I can convert the base64 string to an BitmapImage asynchronously, but cannot bind the resulting image to the front end because properties cannot contain asynchronous functions. How would I go about doing this as all the solutions I have found thus far are not applicable to UWP.
Thank you for the help.
Upvotes: 0
Views: 2094
Reputation: 137
Here's a code snippet for you to refer to. You can download the full solution here: code.msdn.
Write two properties in the viewmodel. When we set string value to encodedImage property, we call an async method to convert it to writeablebitmap type value and set the converted result to the other property selectedImage. Selected Image is the binding source of xaml Image control.
public class MainViewModel : INotifyPropertyChanged
{
private string encodedImage;
public string EncodedImage
{
get
{
return encodedImage;
}
set
{
encodedImage = value;
// Convert source to writeblebitmap and set value to SelectedImage
ConvertToImage(value);
NotifyPropertyChanged("EncodedStream");
}
}
private WriteableBitmap selectedImage;
public WriteableBitmap SelectedImage
{
get { return selectedImage; }
private set { selectedImage = value; NotifyPropertyChanged("SelectedImage"); }
}
/// <summary>
/// Convert encoded string to writeblebitmap
/// set result value to SelectedImage
/// </summary>
/// <param name="base64String"></param>
public async void ConvertToImage(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(bytes.AsBuffer());
stream.Seek(0);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
WriteableBitmap writebleBitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
await writebleBitmap.SetSourceAsync(stream);
// When SelectedImage value is changed, it will notify the front end
SelectedImage = writebleBitmap;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
Upvotes: 1
Reputation: 4327
The first is convert the base64 to bit array.
You can use Convert.FromBase64String
convert base64 to byte[]
var bytes = Convert.FromBase64String(base64);
But byte[] cant be stream that you should convert byte[] to buffer
var buf=bytes.AsBuffer();
And you can change it to stream.
var stream=buf.AsStream();
And you can use the stream for new BitmapDecoder
var image = stream.AsRandomAccessStream();
var decoder = await BitmapDecoder.CreateAsync(image);
image.Seek(0);
And you can use the WriteableBitmap that convert it to ImageSource.
var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
await output.SetSourceAsync(image);
return output;
Then you can set the Image source to what you want to show.
See convert bitmap WriteableBitmap ,convert base64ToImage
If you want bind the imagesource to Image.Source that you should add a class that have a property.
public ImageSource Source
{
get { return _source; }
set { _source = value; OnPropertyChanged();}
}
The OnPropertyChanged is INotifyPropertyChanged that you can use it in github
And you can use the convert base64 to image source and set the Source.
You can bind it to page and see the image show the base64.
Upvotes: 4