evanw / thumbhash

A very compact representation of an image placeholder
https://evanw.github.io/thumbhash/
MIT License
3.49k stars 69 forks source link

Increase quality? #39

Closed lilouartz closed 1 month ago

lilouartz commented 1 month ago

Is there a way to increase quality?

My use case is showing a placeholder for product labels such as this https://pillser.com/supplements/vitamin-b1-3254

The current placeholders are not doing great job representing such content

Is there a way to increasing the quality/detail level of thumbhash trading for size?

evanw commented 1 month ago

This library doesn't provide a way to do that. One could imagine potentially modifying this library to use more coefficients. However, as you increase the quality, other image formats will likely quickly become more optimal than this format, so you'd likely want to use them instead. That's because this library is tuned for very small sizes and doesn't do things that you'd want to do at larger sizes such as compression of coefficients (e.g. with RLE, LZW, etc.). So I don't think it makes sense to extend the ThumbHash format to support increasing quality.

I recommend trying some of the different modern formats available on https://squoosh.app/ and seeing what you can get. For example, here's a 256-byte version of the image you linked to using the WebP format:

<img src="data:image/webp;base64,UklGRvYAAABXRUJQVlA4IOoAAADQBACdASogABAAPpU8mEgloyKhMAgAsBKJbACw/f/l2CMLS7/i1AhgIbenLu2iwAD+/rWmSGhOkadIMzATO5xQI3DPut9Y90A3JUOqKXS7otAX7tFC6vb9Hn+cwJfL8IHf3993EzPqp6Suazg1aafzROh0VqUeP15q+BBJ46R2xWK27e7GG+159tUXDJvEVbOfv/f98tlcvIUy23J2JvzhVq0pf+aL1wr0ML7szEVLWCDmGLctgVyjC+ueeGiXYOnvdnXeytfvnQw1x5AKwG6rgdDerTQo2mItftSm+wgNRwh5h3eQHY4AAAA=" width="640" style="filter:blur(10px);clip-path:inset(0)">

You should be able to generate images like that with a WebP encoding library.

lilouartz commented 1 month ago

Is there anything that squoosh would do that https://github.com/lovell/sharp doesn't already do?

I've tried this:

const buffer = await sharp(imageBuffer)
  .resize(100)
  .blur(10)
  .avif()
  .toBuffer();

and got:

AAAAHGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZgAAAOptZXRhAAAAAAAAACFoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAAAAAAA5waXRtAAAAAAABAAAAImlsb2MAAAAAREAAAQABAAAAAAEOAAEAAAAAAAAAcAAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAAamlwcnAAAABLaXBjbwAAABNjb2xybmNseAABAA0ABoAAAAAMYXYxQ4EgAgAAAAAUaXNwZQAAAAAAAABkAAAAPwAAABBwaXhpAAAAAAMICAgAAAAXaXBtYQAAAAAAAAABAAEEAYIDBAAAAHhtZGF0EgAKCTgZcfzCAhoNIDJhFAAEECCCAMvj0adPy3pD0g0SqZqsJsrVqfYc3QtBr3ZvTDW+kGeRvhsLHKZ9WeCZsJ7JSf5y2pRf8YGwPDOvpG3iNqAWprkA3qtdd7qi4BJDuJc251YUJ50pB0Wl7pgFMA==

evanw commented 1 month ago

I assume both squoosh and sharp are using similar libraries (e.g. libwebp) under the hood, so you'd think it'd be possible to get similar output in both. However, you'll likely want to play with the quality settings for these codecs to trade off quality vs. output size.

lilouartz commented 1 month ago

Thanks. I got something that works decently well

https://pillser.com/supplements/womens-multivitamin-20606

It is quite bigger than thumbhash, for my use case, it makes sense.