I have below XAML code :
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
WindowStartupLocation="CenterScreen"
Title="Window1" Height="300" Width="300">
<Grid>
<Image x:Name="TestImage" Source="{Binding Path=ImageSource}" />
</Grid>
</Window>
Also, there is a method that makes an Image from a Base64
string :
Image Base64StringToImage(string base64ImageString)
{
try
{
byte[] b;
b = Convert.FromBase64String(base64ImageString);
MemoryStream ms = new System.IO.MemoryStream(b);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
//////////////////////////////////////////////
//convert System.Drawing.Image to WPF image
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(img);
IntPtr hBitmap = bmp.GetHbitmap();
System.Windows.Media.ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
Image wpfImage = new Image();
wpfImage.Source = imageSource;
wpfImage.Width = wpfImage.Height = 16;
//////////////////////////////////////////////
return wpfImage;
}
catch
{
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri(@"/passwordManager;component/images/TreeView/empty-bookmark.png", UriKind.Relative));
img1.Width = img1.Height = 16;
return img1;
}
}
Now, I'm gonna bind TestImage
to the output of Base64StringToImage
method.
I've used the following way :
public string ImageSource { get; set; }
ImageSource = Base64StringToImage("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABjUExURXK45////6fT8PX6/bTZ8onE643F7Pf7/pDH7PP5/dns+b7e9MPh9Xq86NHo947G7Hm76NTp+PL4/bHY8ojD67rc85bK7b3e9MTh9dLo97vd8/D3/Hy96Xe76Nfr+H+/6f///1bvXooAAAAhdFJOU///////////////////////////////////////////AJ/B0CEAAACHSURBVHjaXI/ZFoMgEEMzLCqg1q37Yv//KxvAlh7zMuQeyAS8d8I2z8PT/AMDShWQfCYJHL0FmlcXSQTGi7NNLSMwR2BQaXE1IfAguPFx5UQmeqwEHSfviz7w0BIMyU86khBDZ8DLfWHOGPJahe66MKe/fIupXKst1VXxW/VgT/3utz99BBgA4P0So6hyl+QAAAAASUVORK5CYIII").Source.ToString();
but nothing happen.
How can I fix it ?
BTW, I'm dead sure that the base64 string is correct
Let's break down what you're doing.
<Image Source="{Binding ImageSource}" />
For this to work, the binding source needs to be either an ImageSource, or a string representing a URI to an image file. So let's take a look at what the ImageSource property actually is.
public string ImageSource { get; set; }
One problem here is that ImageSource isn't raising PropertyChanged events. So WPF won't update the binding target when you update the property.
But also, ImageSource isn't an ImageSource, it's a string. That's okay, but WPF is going to interpret that string as a URI. What is that URI?
ImageSource = Base64StringToImage(BIG_HONKING_STRING).Source.ToString();
This is the nub of your problem. The ImageSource string isn't actually a URI, because your image isn't an addressable resource. Base64StringToImage creates an in-memory ImageSource from the base64 string, then return an Image with that as its Source. Then you take the Image's Source (which is an ImageSource object), and stringise that. That might work if the ImageSource had come from a file or URL, but it didn't: it came from a HBITMAP. So the result of ToString() is going to be meaningless. So ImageSource is being set to something meaningless, and your Image is trying to interpret this meaningless thing as the URL of a bitmap file.
So to fix this you need to do three things:
Base64StringToImage(...).Source
-- i.e. remove the ToString() call. Better still, change Base64StringToImage to return an ImageSource rather than an Image: creating an Image element just creates overhead because all you're really interested in is the BitmapSource.As a complement to @itowlson's excellent answer, this is what your code should look like:
// MainWindow.xaml
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Image Source="{Binding ImageSource}" />
</DockPanel>
</Window>
// MainWindow.xaml.cs
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var model = new MainModel();
DataContext = model;
model.SetImageData(File.ReadAllBytes(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"));
}
}
class MainModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void SetImageData(byte[] data) {
var source = new BitmapImage();
source.BeginInit();
source.StreamSource = new MemoryStream(data);
source.EndInit();
// use public setter
ImageSource = source;
}
ImageSource imageSource;
public ImageSource ImageSource
{
get { return imageSource; }
set
{
imageSource = value;
OnPropertyChanged("ImageSource");
}
}
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With