Awesome
BlurHashExt
Kotlin extensions of BlurHash on Android ImageView, Glide, and Picasso.
Based Blurhash implementation is from https://github.com/woltapp/blurhash.
This implementation focus on optimizing BlurHash for Android development.
How BlurHash works?
In short, BlurHash takes an image, and gives you a short string (only 20-30 characters!) that represents the placeholder for this image. You do this on the backend of your service, and store the string along with the image. When you send data to your client, you send both the URL to the image, and the BlurHash string. Your client then takes the string, and decodes it into an image that it shows while the real image is loading over the network. The string is short enough that it comfortably fits into whatever data format you use. For instance, it can easily be added as a field in a JSON object.
BlurHashExt implements BlurHash Algorithm(request to generate bitmap from the blurHash and convert to drawable) using coroutine. This allows image processing to happen on the IO thread. Call blurHash.clean()
to dispose any pending job operation and other cache bitmap. BlurHash
uses LRU-Cache to cache drawable bitmap in memory. lruSize
can be defined when initializing BlurHash
.
In summary:
<img src="Media/HowItWorks1.jpg" width="250"> <img src="Media/HowItWorks2.jpg" width="250">
Want to know all the gory technical details? Read the algorithm description.
Download
Gradle:
dependencies {
implementation 'xyz.belvi.blurHash:blurHash:1.0.4'
}
Usage
Step 1 - Initialize BlurHash
val blurHash: BlurHash = BlurHash(this, lruSize = 20, punch = 1F)
lruSize
determines the number of blur drawable that will be cache in memory. The default size is 10
Step 2 - Using BlurHash
With Glide
Glide.with(this).load(imgUrl)
.blurPlaceHolder(blurHashString, imageView, blurHash)
{
requestBuilder ->
requestBuilder.into(imageView)
}
or
Glide.with(this).load(imgUrl)
.blurPlaceHolder(blurHashString, width = 200, height= 200, blurHash = blurHash)
{
requestBuilder ->
requestBuilder.into(imageView)
}
With Picasso
Picasso.get().load(imgUrl)
.blurPlaceHolder(blurHashString, imageView, blurHash)
{
request ->
request.into(imageView)
}
or
Picasso.get().load(imgUrl)
.blurPlaceHolder(blurHashString, width = 200, height= 200, blurHash = blurHash)
{
request ->
request.into(imageView)
}
With Coil
val request = ImageRequest.Builder(context)
.data("https://www.example.com/image.jpg")
.target { drawable ->
// Handle the result.
}.blurPlaceHolder(blurHashString, imageView, blurHash = blurHash)
{coilImageBuilder ->
coilImageBuilder.build()
}
or
imageView.load("https://www.example.com/image.jpg") {
crossfade(true)
blurPlaceHolder(blurHashString, imageView, blurHash = blurHash)
{coilImageBuilder ->
coilImageBuilder.build()
}
transformations(CircleCropTransformation())
}
In an ImageView
This is useful for loading a placeholder before makeing a call to load the actual Image
imageView.placeHolder(blurHashString, blurHash)
{
imageView.setImageURI(imgUrl)
}
Just interested in getting the blurHash Drawabe ?
This is useful for getting blurHasdDrablw asynchronously.
blurHashDrawable(blurHashString, imageView, blurHash)
{
drawable ->
// do something with drawable or use whatver imageloading library you want. blurDrawable is ready to be used as error image or placeholder
}
or
blurHashDrawable(blurHashString, width = 200, height = 200, blurHash)
{
drawable ->
// do something with drawable or use whatver imageloading library you want. blurDrawable is ready to be used as error image or placeholder
}
Step 3 - Finally, Disposing
On onDestroy
, do not forget to clean cached bitmap and tell BlurHash
to cancel any pending coroutine transaction. Here's how :
override fun onDestroy() {
super.onDestroy()
blurHash.clean()
}
What is the punch
parameter in some of these implementations?
It is a parameter that adjusts the contrast on the decoded image. 1 means normal, smaller values will make the effect more subtle, and larger values will make it stronger. This is basically a design parameter, which lets you adjust the look.
Technically, what it does is scale the AC components up or down.
Contributing
Contributions are welcomed even to blurHash base library!
You can also contribute by reporting issues or helping to resolve issues listed here issue tracker or file a pull request.