6 ms·
Blurhash: A compact representation of a placeholder for an image
- deleted 4y ago[deleted]
- learndeeply 4y agoPrevious discussion: https://news.ycombinator.com/item?id=22374825 https://news.ycombinator.com/item?id=22374825 Wonder if anyone's turned Instagram's version of Blurhash into a library?
- darekkay 4y agoI am using blurhash on my photography website and it works and looks great. But given all the examples and libraries out there, more DIY work than expected was required to implement the main use case for blurhash end-to-end in vanilla JS.
- trinovantes 4y agoIs the space savings of using a custom base83 encoding really worth it when modern browsers can natively support base64 image encodings?
- PostOnce 4y agobase85 is already fairly widely supported also in libraries for many languages, its in python's standard lib https://en.wikipedia.org/wiki/Ascii85 https://en.wikipedia.org/wiki/Ascii85
- jerjerjer 4y agoIt's base83 hash, not base83 image so using base64 won't help any.
- trinovantes 4y agoIt seems more like a modified version of jpg compression which also uses DCT. Why not just downsample the original image to 10x10 jpg and encode it as base64 so it can be directly used in an <img> without blocking your main JS thread to decode the image? Apply css blur if you like the soft gradient effect.
- nicoburns 4y agoBecause a raster format is going to be very inefficient for storing a gradient
- trinovantes 4y agoBoth formats are trying to encode the parameters of cosine functions except jpg is implemented natively in web browsers, likely with SIMD instructions. Is the ~200 bytes in savings per image really worth the extra computation cost you're passing onto your users?
- mark-r 4y agoI wonder if you could use Javascript to convert the hash into a full JPEG and get the best of both?
- trinovantes 4y agoIt's unlikely since the smallest possible jpg 10x10 jpg is just under 300 bytes. You might be able to squeeze out a few dozen bytes if you tried multiple browser supported formats (e.g. jpg, webp, png, gif) and pick the smallest one since they might be better at encoding blurhash's gradient effect.
- mark-r 4y agoI'm sorry, I wasn't clear about what I meant. The idea was to convert the hash to JPEG once it reached the client, so that the browser's native JPEG support could be used to display and cache the image.
- mark-r 4y agoIn this case it looks like a key consideration is the way each data point fits into exactly 2 characters, no tricky bit manipulation going on. I'd say it's pretty clever.
- codedokode 4y agoWhat are memory and CPU costs of using this in web pages? For example, when a page with 100 images loads, won't decompressing hashes into 100 canvases take lot of resources and block the page or entire system for several seconds? The placeholders are blurred and I assume that creating blurred images is pretty expensive and takes O(N^2*M) where N is size of the image and M is number of points. Wouldn't it be cheaper to use blocky placeholders that take only O(N^2) time to paint?
- onion2k 4y agoWhat are memory and CPU costs of using this in web pages? For example, when a page with 100 images loads, won't decompressing hashes into 100 canvases take lot of resources and block the page or entire system for several seconds? If you're sensible and use small input images, and therefore small hashes, it should be fine. It's not actually doing all that much 'work'. Besides, browsers are much faster than people think they are, especially for things like canvas drawing because that happens on the GPU (even in a 2d context.) I assume that creating blurred images is pretty expensive. The input image is converted to a hash. When the placeholder is needed the hash is converted to a gradient. Essentially it's like picking a few points in an image and then using a gradient function to fill in the spaces between the points. That's something that's easy for a computer for do quickly. Also, as it happens, blurring an image is fast too. You can implement a Gaussian blur in a convolution filter, and that's just a simple matrix.
- RunSet 4y ago> browsers are much faster than people think they are Does "people" include you? Also web pages are more bloated than people think they are.
- onion2k 4y agoDoes "people" include you? Without wishing to create a paradox, it absolutely does, yes. I've been a web dev since 1997 and I frequently have to remind myself that I don't always need to optimize things, memoize things, or throw features out based on browser performance any more. I constantly underestimate what browsers are capable of. There's a 'pandemic' of over-optimization that heaps complexity (aka bloat) into web apps unnecessarily based on the mostly wrong belief that browsers are slow. Devs need to be careful, and they need to measure things. They shouldn't start with the assumption that something will be slow. What's really interesting about this whole question is that HN's least favorite frontend library, React, suffers this problem. The virtual DOM implementation was necessary a decade ago when React started, but DOM manipulation has been optimized in browsers so now the vdom is actually a bit of a hinderance (React has advantages other than speed, so it's still a fine choice.) Libraries that HN likes, such as Svelte and Solid, rely on the browser to be fast, because the browser is fast.
- z33k 4y agoNot sure why I would want to use this instead of progressive image decoding with a (CSS?) blur filter. Instead of a blurred image suddenly flashing to a fully loaded image, the user would see the image quality gradually improve as it loads over the network. Then again, progressive JPEG or FLIF is not supported that well anywhere, so I guess this could be the best thing right now because it seems to just require HTML5 canvas.
- crimsonnoodle58 4y agoA blurhash is much easier to send along with the JSON data used to display the initial page. To see a blurred version of a progressive JPEG the browser must have first started to download that JPEG. When there are many JPEG's to download, it may not even have started downloading yet.
- divan 4y agoI typically store it in the DB along with the image ID (or URL). It's being displayed even before network request to the actual image has started. Works like a charm on slow networks.
- zulu-inuoe 4y agoStore what? The BlurHash ?
- divan 4y agoCorrect. It's just 20-30 bytes of data.
- sirn 4y agoMastodon, for example, use it to defer loading of images tagged with Content Warning until the user clicked reveal. It provides a useful context for user to decide whether to view the image, while not require browsers/clients to load the image beforehand.
- nikeee 4y agoThese blurry images look like they are composed of a couple of gradients. Wouldn't it be possible to generate a tiny SVG or some CSS that reproduces these gradients? In that case, basically no decoding step is needed and integration is as easy as setting a CSS style on a div or including an SVG. If the image dimensions are set from the start, the browser can even continue layouting the page before actually drawing the gradients. Letting the browser decode the gradients should also be much faster. Is there a library that does that?
- jesuscript 4y agoSomeone can correct me, but gradients and large box shadows are some of the most intensive things your browser can render. There was noticeable slowdown when you do too much of that.
- notpushkin 4y agoThere certainly is an SVG thing but I don't remember the name. I think Blurhash is the way it is because Wolt is an app and not a website, so the decoder is already loaded when you open it. For browser use, SVG would be more straightforward.
- mark-r 4y agoSVG would be much larger for the same image, it's XML based.
- SergeAx 4y agoIt would be nice if there was a way to translate/transcode Blurhash directly to SVG with a small piece if TS code.
- notpushkin 4y agoTrue, but we have GZip for that, and you don't need a lib to parse it. Actually, it would be nice to compare the overall size needed for both Blurhash lib + a bunch of hashes vs a bunch of SVG placeholders glued together.
- mfsch 4y agoI wish something like this was used for the Signal message history, similar to what WhatsApp does. As it is now, you either have an ever growing message database full of pictures you don’t need to keep around, or you start deleting them and end up with weird gaps in your message history. Keeping a few bytes of data as a placeholder for deleted images would be optimal in my opinion.
- b4je7d7wb 4y agoSeems like signal already uses it for non downloaded images, so your suggestion should be simple enough for them to implement.
- aloer 4y agoI was hoping this would include the unblur animation that wolt uses in their app. It’s a joy to use when it resolves those placeholders piece by piece into the original
- jylam 4y agoSomething related somehow, from 13 years ago, to fit an image in the (then) 140 characters on Twitter: https://www.flickr.com/photos/quasimondo/3518306770 https://www.flickr.com/photos/quasimondo/3518306770
- Dwedit 4y agoI've seen something similar before, where a specific JPEG header and specific quantization matrices was added to user-provided binary data to make the very low-res images. That method uses the native JPEG decoder, so it's fast.
- Scaevolus 4y agoInstagram does this, sending media previews as ~350B base64 strings with constant (well, almost-- they change the width and height) 607B JPEG headers.
- cpeterso 4y agoDo websites still use progressive JPEGs? The blurhash is much smaller than the data needed to render a progressive JPEG's first pass, but would the progressive rendering on top of the blurhash still be worthwhile on today's fast networks?
- darekkay 4y ago> would the progressive rendering on top of the blurhash still be worthwhile on today's fast networks I'm experiencing bad connections all the time, especially while travelling. Additionally, mobile plans are quite expensive in Germany compared to many other countries. So yes, I try to save bandwidth when possible, e.g. by offering AVIF and WebP in addition to PNG and JPEG files on my blog.
- akrymski 4y agoDCT based algo, nice! But what's wrong with using just 4 pixels to represent an image and then blurring that in CSS?
- modeless 4y agoI really dislike these and similar super blurry image replacements. They look ugly to me. Just use one color until the image loads, that's way simpler and doesn't look worse than these.