2

In a ValueConverter, I was trying to convert a System.Data.Linq.Binary (SQL CE image) to a BitmapImage. This method works (image is show correctly on the form):

public object Convert(object value, Type targetType, object parameter, 
                                                     CultureInfo culture) {
    Binary binary = value as Binary;
    if (binary != null) {
        BitmapImage bitmap = new BitmapImage();
        bitmap.BeginInit();
        bitmap.StreamSource = new MemoryStream(binary.ToArray());
        bitmap.EndInit();
        return bitmap;
    }
    return null;
}

This method does NOT work (but no exception is thrown, strangely):

public object Convert(object value, Type targetType, object parameter, 
                                                     CultureInfo culture) {
    Binary binary = value as Binary;
    if (binary != null) {
        using (var stream = new MemoryStream(binary.ToArray())) {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            return bitmap;
        }
    }
    return null;
}

Good programming practice states that you should dispose of any streams you create... so I'm confused why the second method doesn't work, but the first does. Any insights?

Mark Carpenter
  • 17,445
  • 22
  • 96
  • 149
  • I have some simpler sample code here: http://erikej.blogspot.com/2009/11/how-to-save-and-retrieve-images-using.html – ErikEJ Jan 23 '11 at 10:00
  • Your conversion code from byte[] to Image uses `Image.FromStream(ms);` which appears to be Windows Forms specific (I'm using WPF). I checked `System.Windows.Media.Imaging.BitmapImage` and `System.Windows.Controls.Image`, and neither of them had a `FromStream` method. Thanks for the link though. – Mark Carpenter Jan 23 '11 at 15:27

2 Answers2

2

Try this instead:

public object Convert(object value, Type targetType, object parameter, 
                                                     CultureInfo culture) {
    Binary binary = value as Binary;
    if (binary != null) {
        using (var stream = new MemoryStream(binary.ToArray())) {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.CacheOption = BitmapCacheOption.OnLoad; 
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            bitmap.Freeze(); 
            return bitmap;
        }
    }
    return null;
}

In your non-working version, your using block means the stream is closed before the image is actually decoded.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
0

My guess would that when you are disposing the MemoryStream, you are nullifying the StreamSource of the bitmap. So, when the bitmap tries to render, there is no valid data available.

devuxer
  • 41,681
  • 47
  • 180
  • 292
  • but he returns the bitmap before the `MemoryStream` is disposed, doesn't it? – VoodooChild Jan 23 '11 at 03:49
  • @VoodooChild, Good point, but is it possible WPF doesn't try to actually render the bitmap until after `Dispose()` has been called? – devuxer Jan 23 '11 at 03:55