2

I am trying to create a BitmapImage from a byte array which is returned by a service.

My code is:

using (sc = new ServiceClient())
{
    using (MemoryStream ms = new MemoryStream(sc.GetImage()))
    {
        Display = new BitmapImage();
        Display.BeginInit();
        Display.StreamSource = ms;
        Display.EndInit();
    }
}

However, an exception is thrown at the EndInit method. It says Object reference not set to an instance of an object..

It seems, that Uri is null and it causes the problem. Unfortunately, I cannot find a solution myself.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Dmitry Korolev
  • 675
  • 4
  • 20
  • According to the [documentation](http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.streamsource.aspx), do you also assign a value to `Display.UriSource`? If so, it will ignore the `StreamSource`. In addition, do you have the `CacheOption` property set to `BitmapCacheOption.OnLoad`? EDIT: Also, it appears that `Display` is a member (field/property), is it possible you have a threading issue here that replaces/changes `Display` as you're working with it? – Chris Sinclair May 18 '13 at 15:30
  • @ChrisSinclair, I do not assign a vaule to UriSource. I just checked a stack trace and it seemed to me, that a null pointer exception is thrown due to this attribute. It was just a guess. Display is a property indeed, which is bound to my XAML layout. So, basically I would like to get an image from the WCF service and then display it at the WPF window. Besides this binding, I do not have code, which can cause a threading issue. – Dmitry Korolev May 18 '13 at 15:59
  • Can you try setting its `CacheOption` property to `BitmapCacheOption.OnLoad`? Otherwise, from what I understand, it will lazily try to access the stream which may be closed by the time it reads it. According to comments [here](http://stackoverflow.com/a/2250851/1269654) be sure to set it after `BeginInit()`. EDIT: that is: `Display = new BitmapImage(); Display.BeginInit(); Display.CacheMode = BitmapCacheOption.OnLoad; Display.StreamSource = ms; Display.EndInit();` – Chris Sinclair May 18 '13 at 16:09
  • @ChrisSinclair, BitmapImage does not have CacheMode property, I suppose you are reffering to CacheOption one instead. Unfortunately, adding this line did not help. I still have a null pointer exception... – Dmitry Korolev May 18 '13 at 16:41
  • Yeah, it was a typo, sorry. Glad you managed to figure out the problem! – Chris Sinclair May 18 '13 at 16:52

2 Answers2

4

Well, it turned out, that WPF binding was causing the error.

private BitmapImage _display;
public BitmapImage Display
{
    get { return _display; }
    set
    {
        _display = value;
        RaisePropertyChanged("Display");
    }
}

I resolved the issue by getting an image not in the property Display itself, but rather in the filed _display. So, the following is working fine.

using (sc = new ServiceClient())
{
    using (MemoryStream ms = new MemoryStream(sc.GetImage()))
    {
        _display = new BitmapImage();
        _display.BeginInit();
        _display.CacheOption = BitmapCacheOption.OnLoad;
        _display.StreamSource = ms;
        _display.EndInit();
    }
}

Display = _display;
Dmitry Korolev
  • 675
  • 4
  • 20
1

u are assigning memory stream directly to the bitmap source, which causes error. first u need to get that array of bytes & than convert it into the memory stream and then assign to the bitmap source, that's it !!!

using (sc = new ServiceClient())
    {
            Byte[] array = sc.GetImage();

            Display = new BitmapImage();
            Display.BeginInit();
            Display.StreamSource = new MemoryStream(array);
            Display.EndInit();
     }
Ashok Damani
  • 3,896
  • 4
  • 30
  • 48
  • 1
    I didn't know you could have `using` on a `byte[]`; I thought it _must_ be `IDisposable`. EDIT: Quick test, I don't think you can. How is this code (assuming you fix it) any different than what's supplied? It just avoids disposing the stream? – Chris Sinclair May 18 '13 at 15:25
  • The description in your updated answer is _exactly_ what Dmitry is already doing. The _only_ difference between your answer and his original code is that your answer doesn't dispose the memory stream. – Chris Sinclair May 18 '13 at 15:43
  • Well, as @ChrisSinclair said, your code causes the same behaviour as one in my question with the only difference: in your case the memory stream stays in the memory forever. Unfortunately, the same exception is thrown. – Dmitry Korolev May 18 '13 at 16:02