Using ImageSource.FromStream in code-behind

When developing apps using the Xamarin platform there’s an easy way to load images in code-behind. But it comes with a gotcha. Read on.

The basics

The ImageSource class has a few helper methods to easily load images in various ways. I commonly use it when I want to bind my xaml to a dynamically loaded image. It could be binding to a profile photo loaded from the server. BUT: when doing this I found it was quite easy to generate exceptions. Example code:

ProfilePhoto = ImageSource.FromStream(() => profilePhotoMemoryStream);

The code above looks simple enough. The FromStream method takes a factory method that should return a Stream representing the photo.

So, what’s the problem?

Well, the documentation actually specifies what to do, and we’ve all read the docs, right? 😉

The FromStream method expects a factory function. Keyword here being factory. This means that every time the FromStream method is called (by the xaml renderer), it should return a new stream. So, change the above code to:

The solution

byte[] profilePhotoByteArray = ...
ProfilePhoto = ImageSource.FromStream(() => new MemoryStream(profilePhotoByteArray));

What we do here is keep a byte array around, and generate a new stream upon every invocation. Don’t worrry, the xaml renderer will Dispose() the stream, so we’re all good 🙂

A note on image caching

It’s very common to want to cache images locally. It speeds up the UI and is generally a Smart Thing™ to do. Give the information above, you want to cache and return byte arrays from your image cache implementation, not MemoryStreams, which would otherwise be the obvious choice.

The good thing is that creating a new MemoryStream from an existing byte array, which is already in memory, is fast and cheap.



, ,