Databinding a System.Drawing.Image into a WPF System.Windows.Image
I’m learning WPF, very slowly, as a background thing.
I’m working very slowly through some WPF at the moment, and discovered something I thought was really odd. The classic .Net Image class — System.Drawing.Image — can’t be easily databound into the WPF Image control.
That seemed crazy to me — it’s like having a PictureBox control without an Image property. I resolved to fix it in the most ‘WPFy’ way I could.
What I’d tried was binding a ListView to a list of objects, like so;
<ListView
ItemsSource="{ Binding Path=. }"
ItemTemplate="{DynamicResource EventTemplate}">
Id bound to an object which declares two properties;
string DisplayName { get; }
System.Drawing.Image Image { get; set; }
I wanted to populate a DataTemplate but if I did this in my template;
<StackPanel Orientation="Horizontal">
<Image Source="{ Binding Path=Image }" />
<TextBlock Text="{ Binding Path=DisplayName }" />
</StackPanel>
The text appears but the image does not. It turns out that WPF can’t find a suitable converter.
So, thanks to Reed Copsey and his very helpful pointer on Stack Overflow, and this tutorial, I’ve found a way I’m happy with; one that doesn’t involve c# code-behind.
I’ve created an IValueConverter which does the conversion from System.Drawing.Image to System.Windows.Media.ImageSource. A big thank-you to Matt Galbraith of Microsoft for providing the core code;
using System;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Windows.Data;
namespace System.Windows.Media
{
/// <summary>
/// One-way converter from System.Drawing.Image to System.Windows.Media.ImageSource
/// </summary>
[ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
// empty images are empty...
if (value == null) { return null; }
var image = (System.Drawing.Image)value;
// Winforms Image we want to get the WPF Image from...
var bitmap = new System.Windows.Media.Imaging.BitmapImage();
bitmap.BeginInit();
MemoryStream memoryStream = new MemoryStream();
// Save to a memory stream...
image.Save(memoryStream, image.RawFormat);
// Rewind the stream...
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
return bitmap;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
}
Then you need to bring the image converter into XAML as a resource. Add the namespace declaration to the window;
xmlns:med="clr-namespace:System.Windows.Media"
Stick an instance of the ImageConverter into a static resource;
<ListView.Resources>
<med:ImageConverter x:Key="imageConverter" />
</ListView.Resources>
Then you can use it in XAML to bind directly to the Image, using the new converter;
<Image Source="{ Binding Path=Image, Converter={StaticResource imageConverter} }" />
So. A re-usable converter which allows databinding directly to GDI image objects.
Originally discussed on stack overflow







Thanks a lot! Short and clear explanation!
I’m also learning WPF as a background thing
I tried this, and my images, which have a transparent background, are now displayed with a black background.
@Alex; try poking around in the System.Windows.Media.Imaging namespace. My guess is that the System.Windows.Media.Imaging.BitmapImage class isn’t handling the alpha channel present in your image. I notice that there are PngBitmapDecoder and PngBitmapEncoder classes, which may or may not help.
(http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.aspx)
To preserve all features of the original image, I think you should replace
image.Save(memoryStream, ImageFormat.Bmp);
with
image.Save(memoryStream, image.RawFormat);
By doing this, you’ll keep features like transparency/alpha channels from image formats like PNG.
Thanks, Gunnar — Updated.
Great, thanks!
Hey Steve. Thanks for the post. I wanted to share a VB.Net conversion I made on the code you provided in case anybody else is looking for one.
http://blakepell.wordpress.com/2011/12/22/databinding-a-system-drawing-image-in-wpf-with-vb-net/
Thanks a lot! I’ve spent 2 days on it without any result.
where is the corret position of this code?
I don’t know to create a good static resources.
Thanks a lot!