blurhash README

The project's README from github.com/woltapp/blurhash. As one markdown file: README.md.

BlurHash

BlurHash is a compact representation of a placeholder for an image.

Why would you want this?

Does your designer cry every time you load their beautifully designed screen, and it is full of empty boxes because all the images have not loaded yet? Does your database engineer cry when you want to solve this by trying to cram little thumbnail images into your data to show as placeholders?

BlurHash will solve your problems! How? Like this:

You can also see nice examples and try it out yourself at blurha.sh!

How does it work?

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.

In summary:

   

Want to know all the gory technical details? Read the algorithm description.

Implementing the algorithm is actually quite easy! Implementations are short and easily ported to your favourite language or platform.

Implementations

So far, we have created these implementations:

These cover our use cases, but could probably use polishing, extending and improving. There are also these third party implementations that we know of:

Can't find the language you're looking for? Try your luck with the GitHub search. For example, here are the search results for repos which have "blurhash" in their name.

Perhaps you'd like to help extend this list? Which brings us to...

Contributing

We'd love contributions! The algorithm is very simple - less than two hundred lines of code - and can easily be ported to your platform of choice. And having support for more platforms would be wonderful! So, Java decoder? Golang encoder? Haskell? Rust? We want them all!

We will also try to tag any issues on our issue tracker that we'd love help with, so if you just want to dip in, go have a look.

You can file a pull request with us, or you can start your own repo and project if you want to run everything yourself, we don't mind.

If you do want to contribute to this project, we have a code of conduct.

Users

Who uses BlurHash? Here are some projects we know about:

Good Questions

How fast is encoding? Decoding?

These implementations are not very optimised. Running them on very large images can be a bit slow. The performance of the encoder and decoder are about the same for the same input or output size, so decoding very large placeholders, especially on your UI thread, can also be a bit slow.

However! The trick to using the algorithm efficiently is to not run it on full-sized data. The fine detail of an image is all thrown away, so you should scale your images down before running BlurHash on them. If you are creating thumbnails, run BlurHash on those instead of the full images.

Similarly, when displaying the placeholders, very small images work very well when scaled up. We usually decode placeholders that are 32 or even 20 pixels wide, and then let the UI layer scale them up, which is indistinguishable from decoding them at full size.

How do I pick the number of X and Y components?

It depends a bit on taste. The more components you pick, the more information is retained in the placeholder, but the longer the BlurHash string will be. Also, it doesn't always look good with too many components. We usually go with 4 by 3, which seems to strike a nice balance.

However, you should adjust the number of components depending on the aspect ratio of your images. For instance, very wide images should have more X components and fewer Y components.

The Swift example project contains a test app where you can play around with the parameters and see the results.

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.

Is this only useful as an image loading placeholder?

Well, that is what it was designed for originally, but it turns out to be useful for a few other things:

Why base 83?

First, 83 seems to be about how many low-ASCII characters you can find that are safe for use in all of JSON, HTML and shells.

Secondly, 83 * 83 is very close to, and a little more than, 19 * 19 * 19, making it ideal for encoding three AC components in two characters.

What about using the full Unicode character set to get a more efficient encoding?

We haven't looked into how much overhead UTF-8 encoding would introduce versus base 83 in single-byte characters, but the encoding and decoding would probably be a lot more complicated, so in the spirit of minimalism BlurHash uses the simpler option. It might also be awkward to copy-paste, depending on OS capabilities.

If you think it can be done and is worth it, though, do make your own version and show us! We'd love to see it in action.

What about other basis representations than DCT?

This is something we'd love to try. The DCT looks quite ugly when you increase the number of components, probably because the shape of the basis functions becomes too visible. Using a different basis with more aesthetically pleasing shape might be a big win.

However, we have not managed come up with one. Some experimenting with a Fourier-Bessel base, targeted at images that are going to be cropped into circles has been done, but without much success. Here again we'd love to see what you can come up with!

Authors

blurhash (woltapp/blurhash)

Searching Database…

17.1K ·GitHub
这是什么东西?BlurHash 是一种紧凑的图片占位符:一个 20-30 个字符的字符串,编码了一张图片的模糊预览,客户端会先把它解码出来显示,等真实图片加载完成后再替换。
它是要安装的应用,还是一个库?它是一种算法,通过一些小型库实现来使用——全部代码不到 200 行,所以很容易移植到任何语言或平台。
我怎么开始使用它?添加你所用语言的实现,在后端对每张图片编码一次,然后把 20-30 个字符的字符串放进你本来就要发给客户端的数据格式里。
它支持我的语言或技术栈吗?官方实现涵盖 C(编码器)、Swift、Kotlin(Android 解码器)、TypeScript 和 Python;第三方移植版还提供 Go、PHP、Java、Rust、Ruby、Elixir、Dart、.NET 等。
编码和解码在性能上有什么坑吗?有:这些实现没有做过优化,处理非常大的图片时会变慢。请对缩小后的图片运行 BlurHash,并把占位图解码成 20-32 像素左右的宽度,由界面来放大显示。
我需要在后端用,还是在客户端用,还是两边都要?两边都要:后端负责编码,并把字符串随每张图片一起存储;客户端则把它解码成占位图,在网络加载真实图片期间显示。
它在手机和网页上都能用吗?可以——官方实现面向 iOS(Swift)、Android(Kotlin)和网页(TypeScript),Wolt 自己就在它的 iOS、Android 和网页客户端里全面使用 BlurHash。
怎么确定 X 和 Y 分量的数量?这看个人喜好:分量越多保留的细节越多,但字符串会更长,效果也可能反而变差。作者们通常用 4 乘 3,再根据图片的宽高比调整数量。
punch 参数是做什么的?它调整解码出来的占位图的对比度:1 是正常,数值越小效果越柔和,越大越强烈。从技术上讲,它是对 AC 分量进行放大或缩小。
BlurHash 只能用作加载占位图吗?不是。它还可以在不使用昂贵的模糊特效的情况下给图片打码(Mastodon 就是这么做的),也能近似估算图片某个区域的平均颜色——整张图的平均颜色就是 DC 分量。
有哪些人在生产环境中使用 BlurHash?Wolt 在 iOS、Android 和网页上使用;Mastodon 用它做占位图和隐藏敏感媒体;Signal 在照片和视频消息下载完成前显示它;Jellyfin 用它显示电影和电视剧的图片。
Creator
woltapp
Size
12 MB
Stars
17.1K
Updated
CommitMay 21
Age
7y
Commits · 90 Days