When building a content rich mobile app with lots of imagery, what we often do make a web request that returns some JSON of content containing image urls for the images we want to load.
When we get the JSON, we can start to show the users some UI, but what do we show them while we go off and get the images? We often use placeholder images for this, this requires designing them, and can be a jarring transition when the real image loads.
BlurHash is an algorithm that lets you compute a hash from an image, this hash encodes a representative blurred image, represented as text.
Take a look at this example from the BlurHash website:
We can do this processing on the server side and store a BlurHash string alongside the image url. Now when we get our JSON data back, we can immediately display a placeholder blur. For the quality of image above, the string will be 28 characters.
There are implementations in many different languages.
A Xamarin Solution
To get this working in a Xamarin app, I started with a .NET implementation here, by Markus Palcer. I then ported it to .NET Standard 2.1, using ImageSharp and some
Span<T> goodness. The port can be seen in this PR.
Once this library is available, all you will need to do to encode is:
var encoder = new Blurhash.ImageSharp.Encoder();var image = Image.Load<Rgb24>(imageBytes);// x and y components = 3, higher will give better detail, but longer hashesvar hash = encoder.Encode(image, 3, 3);
And to decode:
var decoder = new Blurhash.ImageSharp.Decoder();var ms = new MemoryStream();// size: 100px x 100px, you get to choose herevar image = decoder.Decode(hash, 100, 100);image.SaveAsPng(ms);
In Xamarin Forms, we just need to bind to an
ImageSource property, and off we go!
Here is what it looks like:
This is based on FashionApp, by Oludayo Alli.
Why Am I Excited by This?
I think this is really cool for a number of reasons:
- This is a multi-platform solution to this problem - there are lots of implementations - including Swift, Kotlin, WebAssembly, and many system languages.
- There used to be techniques to use data urls to solve this on the web, and it wasn't quite viable, this would encode the resulting image which is relatively huge compared to this string representation.
- The algorithm is super simple! The Kotlin implementation is just over 100 lines of code.
I hope to make the source available for this soon.