Converting a byte array to an image in WinRT

by Rob 11. September 2012 01:42

I've been playing around with WinRT recently and had a simple enough request - to load an image from a file into a byte array and render it in XAML. Only with all the new data types (especially around IO) I found doing this seemingly simple task rather fiddly - so I thought I'd document it here.

Firstly I tried to "go it alone" and work my way through the problem using the intellisense, but this didn't pan out as I ended up needing to supply an IRandomAccessStream (some new WinRT construct) which I had no idea how to do.

I ended up on this blog post which seemed to have a solution, but used a class, MemoryRandomAccessStream which wasn't in the framework (I assumed it was simply something that had changed at RTM, but I later found an implementation of the class here).

Based on the fist post I read, I came up with the following solution;

string path = @"images\mypic.png";
var folder = Package.Current.InstalledLocation;

var file = await folder.GetFileAsync(path);

byte[] imageBytes;

using (var stream = await file.OpenReadAsync())
using (var dataReader = new DataReader(stream))
{
    await dataReader.LoadAsync((uint)stream.Size);

    imageBytes = new byte[stream.Size];
    dataReader.ReadBytes(imageBytes);
}

var image = new BitmapImage();
using(var randomAccessStream = new InMemoryRandomAccessStream())
{
    var writeStream = randomAccessStream.AsStreamForWrite();
    await writeStream.WriteAsync(imageBytes, 0, imageBytes.Length);
    await writeStream.FlushAsync();

    randomAccessStream.Seek(0L);

    await image.SetSourceAsync(randomAccessStream);
}

The resultant BitmapImage can be directly surfaced to XAML via a view model etc. and rendered as required. The BitmapImage takes a copy of the image so the stream can be safely disposed of via the using clause.

The crux of this is the use of SetSourceAsync on BitmapImage, and using the "AsStreamForWrite" extension method on InMemoryRandomAccessStream to populate the stream from the array. On the surface, this to me is a nicer method than implementing a whole new stream class for such a basic task as loading in an image. That said, I don't have a full enough understanding yet of WinRT to know if my method has some underlying performance or resource issue I haven't yet considered, but I'll use it for now.

Tags: ,

Development

Pingbacks and trackbacks (1)+

Comments are closed

About the author

Rob has been involved with software development since his early teens. Starting out with BASIC programming on the ZX81 and Atari ST, before moving to IBM compatible machines primarily using the Microsoft tool chain.

He has experience in many areas of development, such as line of business (LOB) applications, games, web applications and mobile devices.

He currently leads a dual life as both a freelance software engineer providing expertise and software solutions to numerous companies in the UK, as well as the lead developer for a global telecommunications company.

Month List

Page List