Loading images from byte arrays in Windows 8 Store apps (WinRT)

Win8Blue_WebI’ve been porting a library and test applications from .NET Framework 3.5 to a Windows 8 Modern UI Store App (WinRT). Windows 8 Store Apps have a cut down implementation of the .NET Framework so that they are none blocking and always responsive. This means that many of the synchronous APIs we are used to have been removed and we’re forced to use their asynchronous counter parts. It has also meant that we’ve needed to port our library to instead be a Portable Class Library so that we can reuse it in different versions of Windows.

The library I’m working on returns byte arrays contains JPEG image data. In the .NET Framework 3.5 it simply took the byte array fed it into a MemoryStream and then into the BitmapDecoder object. Unfortunately this implementation isn’t possible in Windows 8 Store Apps as the BitmapDecoder is blocking and we don’t have blocking APIs in Windows Store apps.

Our old implementation:

public void SetImage(byte[] data, 
    Windows.UI.Xaml.Controls.Image image)
    MemoryStream stream = new MemoryStream(data);
    var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
    image.Source = decoder.Frames[0];

The new implementation is based around using a InMemoryRandomAccessStream object which we first write the data too, reset the internal pointer to the beginning of the data, and create a BitmapImage object which we then feed into our XAML image object.

Our new implementation:

public async void SetImageFromByteArray(byte[] data, 
    Windows.UI.Xaml.Controls.Image image)
    using (InMemoryRandomAccessStream raStream = 
        new InMemoryRandomAccessStream())
        using (DataWriter writer = new DataWriter(raStream))
            // Write the bytes to the stream

            // Store the bytes to the MemoryStream
            await writer.StoreAsync();

            // Not necessary, but do it anyway
            await writer.FlushAsync();

            // Detach from the Memory stream so we don't close it


        BitmapImage bitMapImage = new BitmapImage();

        image.Source = bitMapImage;