Reputation: 2202
I know how to do it in WinForms
byte[] binaryData = Convert.FromBase64String(bgImage64);
image = Image.FromStream(new MemoryStream(binaryData));
but how do i do the same thing in WPF?
Upvotes: 26
Views: 29659
Reputation: 1067
In a situation I came across, I created a converter to handle the conversion of a Base64 string to a WPF Image. So you can bind it to your base64 string property and let the converter take the rest. The main difference between the accepted answer and my own is the fact that a MemoryStream is an IDisposable resource and should be appropriately handled with either a try/catch/finally that disposes the resource after using it, or with a "using" statement to ensure everything is capture correctly in the Garbage Collector. Otherwise, you can run into memory leaks, or if there are enough images on the larger side, you can run into "OutOfMemory" exceptions.
https://learn.microsoft.com/en-us/dotnet/api/system.io.memorystream?view=net-6.0
https://michaelscodingspot.com/find-fix-and-avoid-memory-leaks-in-c-net-8-best-practices/
public class ByteToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (string.IsNullOrEmpty(value?.ToString()))
return null;
var imgBytes = System.Convert
.FromBase64String(value.ToString() ?? throw new InvalidOperationException());
using var stream = new MemoryStream(imgBytes);
return BitmapFrame.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 1
Reputation: 42227
byte[] binaryData = Convert.FromBase64String(bgImage64);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new MemoryStream(binaryData);
bi.EndInit();
Image img = new Image();
img.Source = bi;
Upvotes: 45
Reputation: 10092
Expanding on Josh's answer above - here's one that uses a ValueConverter so you can use binding instead of setting the image source in the code-behind.
Base64ImageConverter.cs
public class Base64ImageConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string s = value as string;
if (s == null)
return null;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new MemoryStream(System.Convert.FromBase64String(s));
bi.EndInit();
return bi;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
ImageData.cs (used as a data source)
public class ImageData
{
public string Base64ImageData { get; set; }
public ImageData()
{
this.Base64ImageData = "iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAgMSURBVHja7Jl7jFXFHcc/55y5j32C+wCVXV6KwAIrbUBQeUhiixQEiYrUGNC0Bq2CFqsNjSYUrQg+Uk1JbW0VW0I3BCGgFSlYQKBSqKK8W6lCgQ0s7sKye++eOefMTP+4d+/ee3eRpa3ipvySyZnc+5s5v+/vOb85ljGGjkw2HZwuArgI4P8dgAU4QCT57EikACmAwv3ff6SuqF8vSh74HiYa5Y1lf2PJkr+QSLECCFjxq6kcve9RLMcG4VD2y4VMvqcqbT+X0u7duH9yBb22vIX7+Sm6zJzB1DnrvzQEK1feXySATge/dRtjwiepX7qc/BvHMGXKEIYN682GDfupqTkNOFiRMHkjh2M5FpZtQyjMyJF9AA3AgME9uO5SG7H9fczQoZSMHYMWghEjDn0pwm/e/AlAJwFEFr22DR4eyw39YjS8vgRn4EB6TB7PtLuvZ+2a3WzctAd8D/V5LZZwwHHQQUBt7WlyCgu4bXwFvf++g9j2Q+TeMZlInys4cbKRqqXvU1sbwxiwrDSnNalHBhkDxhhs2zqr4MZA5845aG0AIiLxo2Hn9gPszS/kO2MmUr5nGydfWESnSeMZN24Q5eVFOI6NURqMBq0RwqH/oJ58u3eY3HdX4XbpQvHMGejCAtat28f69fvwA0lI5LQOPItMUIDWBqU0va7sypHDtRitsZIMzfzNc6V0MwAEgFYenqc5+Vk1r3xWzbR7x1FxfD+n3lhJ54kTGDiwD6amBuP7GMfCMgn13TkgQsOfNxIePYrcId/AB1at2Ml7G/dkxppprf2URpPPvLwwoZBgQr9cltfHqI9J4vEA08yRZi7PUzQfgSygb3Cy9gA5UfA8tDZorQmFRMtLtMH2JcfmPp8IYsfhsp8+hvF8CIdBOOD7ba6d9fjb5/RnrQ2DKssYd6mkYPM63KEjWC9L+ev2Q7TlTZ065fDBB/9i7dqH+gmAw9MeIGdQBepMwxe/yRiMH4AfUD3nKTJ12Tb5urJdQblj+yH6XFvCqO7dOSQdNm35FGGZDDdrywKJGHAlJt6EiTedo2pYLTLr9p1iPVudk8cYgxAOp6KdePJId64uKSI30kBDQxO2bbcBIEApnRYDnoeKxVHnAmAnUyhgAtUuAK7w28Xn+5oVbx/A930++ccJhHCSQibeo5TCcRK1NhRyMgF0f/VFrHAYKxxGK4WtAoRoKcyBsTC+z7GHHwfHBiEoe/k5TEMjRic2sqLRNtfKWW+ed473PIXnqaR1NEoZ+leWc/BANSrQSQBpLnT9na9TXl5EY6ME4JEf38JNN/YF4PTy1QS7dlI4fXrC1YQDgcYKCUTP8gTPstXEd2yjcPp0Fu+Msep361LChMO5rQQMAo3j2K3926SFVXKenx8lEg0xfXAev6jJpbbexXX9lAXsRBZwaGpqIhrNYdZD4xh7Y1+8Tw9T/cOfoDZu4J/9R2BFImjpoV2JlhLjuix49h3q6mJ0vn08OYMqqX1iHpPqP+bmW65B+gIpPVw3SI2mJp/GRkmf/t3w/IB43M/435WZ88aYR+8ruzDnughFi19idn+Pq68uozGWBSAIPCorr2RJ1f3cPKGSM6vXcGLGTHLLLuOd677Lg4u2o4IA7boYKcGV6ECzfNk27rrrFT7ceYxLpk2l20sLMFs2M23vKn7+2ChKepQhpY+UPq70iURCFBXnM2NoLpeX5hGNCqQMUjzSTfK6CX7lK9b/aT+7qj06X3UVR1zByrf2IV0PnQ5g5qybWLjwdgoaT3H0B7MJllZx+r7ZPHq4Kwvmr0aeiWN7XsKFmiTGkyilcKXNkaN13D39N8yf/0dk18voXvUqQcUAurwwjxevdVIajcU8+vTtypOjcyh++VkeH+gxZEgPYnGPpqZMC0gZIN2AJtdHCIuavBLuPt6PvaGuFOY4xOOSID0GJk0cTOO7mzg+byEF13yT9cMm88xzW4nXnUqetANCwsZID4QNRhMOCzwZpBx28eINbN16kKd+diuDH7yX+PChnHjiaaQcmHLxtWv2MmRiGVMqKtjjhli2YjchW39hNVHK8Ovff4jn+ezedZRwyCEIdOq8ZAF9KyrmHgjamRb/UzLGEAqHuOeOSt7bUc0NQ8uoenMvdXUxHOf8+yohHPbtm5uoxEppamtjrTqd//rCJWsTx7F55sUtSOmxdetBQklttnef9ENdSXF+WiHTmuz7of/JbZHJTp8qmVpFsnip89onXURt0gqZUq0BfO37yfRKHAQK27baZ86vAQlhp6wp0tF0JCtkWKAFAB0XgDGk2rQLSYEf4AjRZh+Q3X6mnYUSQdwyOMsze95eXs4yb+HTSiOlz/DR/bBsiyCp1NZrE6c8rdMAKKVSDXRz3jIZedC0kdOyc2X2muz8l75Xq/sILinKo0evUuaPK6b/FUUUF+UmrWBayZFo7FWmBcBkaAVjsrSUNWj9G+fB2zx8X+H5AUOG9+IPtxZy+dM/4rcjA8aOrcDzFVq38R5MpgUSvm9lmeyrGY5jIxyH1Ss+5v1jitLhwzno5fLakg+xk16RvSbhQiYTgGVduMA1xlBQGKGmuIzRNcP4KL8nl5fmpLTcVmuecS9kzIUtYJZloZXm+Ze34boeuz46QjjstNnQt4BOS6PNm3wd8no0Gkq1nWcTKV1Wu9mEFxrAeVtM63QXSvhTQUG0w33gEM0XL2fO1HfEDzTKAroCg4DSDib8SWC3lWx6C5LPjkQSaLAufqm/COAigIsALij9ewBzvhamSg2pRgAAAABJRU5ErkJggg==";
}
}
Window1.xaml
<Window x:Class="ImageFromData.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageFromData"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<local:Base64ImageConverter x:Key="Base64ImageConverter"/>
<local:ImageData x:Key="ImageData"/>
</Window.Resources>
<Grid DataContext="{StaticResource ImageData}">
<Image Source="{Binding Base64ImageData, Converter={StaticResource Base64ImageConverter}}"/>
</Grid>
</Window>
(root namespace for project is ImageFromData)
Upvotes: 37