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 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? 😉
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:
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.