Oct 17, 2011

Converting an image byte array into a usable WPF BitmapSource

In a couple of our systems at work we store file attachments. The data gets put in a database table as a varbinary column. When we pull this down into our .NET apps, it’s represented as a byte[]. This is convenient to do image processing on it, as well as writing it to a file to be viewed, etc., but what about previewing straight in the application?

Below is a simple IValueConverter for your WPF/Silverlight apps to take a byte[] (that you know is image data) and convert it into something useful. This lets you bind the binary data directly to, say, an Image control or something.

While I did put the class together, I’m fairly certain the code is modified and piecemealed from elsewhere on the internets, though I can’t for the moment remember where so I apologize for not having proper attribution.

/// <summary>
/// Converts binary data into a usable image.
/// </summary>
public class BinaryImageConverter : IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  if (value == null || value.GetType() != typeof(Byte[]))
   return null;

  byte[] binaryData = (byte[])value;

  var bmp = new System.Windows.Media.Imaging.BitmapImage();

  using (System.IO.MemoryStream stream = new System.IO.MemoryStream(binaryData))
  {
   bmp.BeginInit();
   bmp.StreamSource = stream;
   bmp.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
   bmp.EndInit();
  }

  if (bmp.CanFreeze)
   bmp.Freeze();

  return bmp;
 }
 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  if (value == null)
   return null;

  var bmp = (System.Windows.Media.Imaging.BitmapSource)value;

  int stride = bmp.PixelWidth * ((bmp.Format.BitsPerPixel + 7) / 8);

  byte[] binaryData = new byte[bmp.PixelHeight * stride];

  bmp.CopyPixels(binaryData, stride, 0);

  return binaryData;
 }
}

1 comment: