[HN Gopher] Blurhash: A compact representation of a placeholder ...
___________________________________________________________________
Blurhash: A compact representation of a placeholder for an image
Author : notmysql_
Score : 190 points
Date : 2022-11-04 01:40 UTC (21 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| modeless wrote:
| I 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.
| aloer wrote:
| I 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
| mfsch wrote:
| I 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 wrote:
| Seems like signal already uses it for non downloaded images, so
| your suggestion should be simple enough for them to implement.
| learndeeply wrote:
| Previous discussion:
| https://news.ycombinator.com/item?id=22374825
|
| Wonder if anyone's turned Instagram's version of Blurhash into a
| library?
| cpeterso wrote:
| Do 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?
| nikeee wrote:
| These 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 wrote:
| Someone 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.
| wongarsu wrote:
| At that point, why not just create a 6x3px thumbnail in a
| format of your choice and let interpolation take care of the
| gradients.
| wiredearp wrote:
| Supposedly some library called SQIP might handle that as
| explained over on https://medium.com/free-code-camp/using-svg-
| as-placeholders-...
| notpushkin wrote:
| There 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 wrote:
| SVG would be much larger for the same image, it's XML based.
| SergeAx wrote:
| It would be nice if there was a way to translate/transcode
| Blurhash directly to SVG with a small piece if TS code.
| fold_left wrote:
| I had a go at doing this in Rust some time ago
| https://github.com/JamieMason/blurhash-to-css and there is also
| https://plaiceholder.co/.
| warpech wrote:
| Nice!
|
| A CSS Houdini worklet would be another way to represent this
| in CSS.
|
| https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Houdini
|
| https://houdini.how/
| michaelmior wrote:
| Interesting idea using Houdini, although I think browser
| support isn't really good enough yet to justify this.
| jylam wrote:
| Something related somehow, from 13 years ago, to fit an image in
| the (then) 140 characters on Twitter:
| https://www.flickr.com/photos/quasimondo/3518306770
| darekkay wrote:
| I 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.
| Dwedit wrote:
| I'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 wrote:
| Instagram does this, sending media previews as ~350B base64
| strings with constant (well, almost-- they change the width and
| height) 607B JPEG headers.
| codedokode wrote:
| What 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?
| ajconway wrote:
| The amount of work it takes to decode an image is incredibly
| tiny by today's standards:
| https://github.com/woltapp/blurhash/blob/master/C/decode.c
| onion2k wrote:
| _What 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.
| kens wrote:
| > browsers are much faster than people think they are
|
| Serious question: my 2017 MacBook Air grinds to a halt on
| many web pages, especially ones with video animation, to the
| point where I can't type because it drops multiple
| characters. I have to use an ad blocker to make pages
| workable. Is this normal or is there something wrong with my
| machine?
| tokamak-teapot wrote:
| Occasionally I will accidentally not have an ad blocker,
| and yes, the amount of CPU required by them can be
| enormous.
|
| People seem to just be used to them and claim that their
| computers are 'getting slower', but really they don't use
| their computer for anything but web browsing and it's only
| slower because ads are getting worse and worse.
| RunSet wrote:
| > 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 wrote:
| _Does "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_.
| RunSet wrote:
| > Devs need to be careful, and they need to measure
| things. They shouldn't start with the assumption that
| something will be slow.
|
| I disagree. The specs of developers' machines typically
| so far surpass those of users as to make that assumption
| valid more often than not.
|
| Further, the fail case for incorrectly assuming that a
| web page will be fast ranges from it being slow to it
| being unusable, while the fail case for incorrectly
| assuming that a web page will be slow is that it is
| slightly more responsive than expected.
| bmacho wrote:
| > The specs of developers' machines typically so far
| surpass those of users as to make that assumption valid
| more often than not.
|
| Billions of people are using computers that are 100 times
| slower than your machine in different metrics. 100 times
| less space on hard drive, 100 times slower hard drive,
| 100 times slower processor, 8-16 times less memory, etc.
|
| But then they probably won't pay you anyway, also if you
| target them, you have to make compromises that will
| affect the overall quality.
| jokethrowaway wrote:
| I don't know in which world you live in but most websites
| are incredibly unoptimised and over-engineered. They use
| a huge amount of resources on expensive machines and
| bring consumer machines to a grind.
|
| I wish we lived in a pandemic of over-optimization.
| joshuacc wrote:
| It's entirely possible for both things to be true at the
| same time. Tons of developers prematurely optimizing
| things that don't matter because they make assumptions
| about performance. Those assumptions can also mean an
| epidemic of not optimizing things that *do matter*.
| mark-r wrote:
| The blurring in this case is just a natural consequence of
| throwing away all the high-frequency DCT components. And
| since DCT is used to create JPEGs there are highly optimized
| versions available.
| z33k wrote:
| Not 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.
| rbut wrote:
| A 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 wrote:
| I 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 wrote:
| Store what? The BlurHash ?
| divan wrote:
| Correct. It's just 20-30 bytes of data.
| sirn wrote:
| Mastodon, 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.
| [deleted]
| trinovantes wrote:
| Is the space savings of using a custom base83 encoding really
| worth it when modern browsers can natively support base64 image
| encodings?
| PostOnce wrote:
| base85 is already fairly widely supported also in libraries for
| many languages, its in python's standard lib
|
| https://en.wikipedia.org/wiki/Ascii85
| mark-r wrote:
| In 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.
| jerjerjer wrote:
| It's base83 hash, not base83 image so using base64 won't help
| any.
| trinovantes wrote:
| It 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 wrote:
| Because a raster format is going to be very inefficient for
| storing a gradient
| trinovantes wrote:
| Both 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 wrote:
| I wonder if you could use Javascript to convert the hash
| into a full JPEG and get the best of both?
| akrymski wrote:
| DCT based algo, nice! But what's wrong with using just 4 pixels
| to represent an image and then blurring that in CSS?
___________________________________________________________________
(page generated 2022-11-04 23:03 UTC)