sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Converting GIF to WebP in lossless results in a smaller file size and higher image quality compared to lossy

Open AlexanderTheGrey opened this issue 3 years ago • 4 comments

Question about an existing feature

What are you trying to achieve?

I wan to convert GIF files to WebP with good quality and a small file size.

Using lossy compression on the example image "SmallFullColourGIF.gif" results in noticeably lower quality and a larger file.

When converting using lossless compression, the WebP output file is smaller and indistinguishable from the original GIF.

When you searched for similar issues, what did you find that might be related?

Lossy compression should yield a smaller file size than lossless compression.

https://www.keycdn.com/support/lossy-vs-lossless

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

Lossless:

const image = sharp(input.gif, { animated: true }).webp({ quality: 100, lossless: true, effort: 1 })

image.toFile(output.webp, (err) => {
    if (err === null) {
      console.log("Success");
    } else {
      console.log("Error")
    }
  });

Lossy:

const image = sharp(input.gif, { animated: true }).webp({ quality: 100, effort: 1 })

image.toFile(output.webp, (err) => {
    if (err === null) {
      console.log("Success");
    } else {
      console.log("Error")
    }
  });

Please provide sample image(s) that help explain this question

https://en.wikipedia.org/wiki/GIF#/media/File:SmallFullColourGIF.gif

AlexanderTheGrey avatar Jun 13 '22 21:06 AlexanderTheGrey

Have you tried using the gif2webp command line tool with the same options to help eliminate sharp/libvips? My best guess would be that this is a libwebp thing.

lovell avatar Jun 13 '22 21:06 lovell

The default settings for gif2webp is lossless. gif2webp conversion using the default options converts the GIF into a much smaller file size and visually identical quality compared to sharp with default settings, which uses lossy as default.

gif2webp uses quality as a measure of compression with the default lossless compression, and sharp more efficiently compresses the WebP file when using maximum CPU. However, sharp still produces a significantly (15%) larger file size with maximum effort using lossy vs sharp lossless at minimum CPU effort.

When choosing the lossy setting for gif2webp, the same behavior occurs, where the quality is much lower, with obvious artifacting, and the file size is much larger than the original GIF.

So this seems to be a general issue of creating a lossy WebP from an animated image (GIF in this case).

Maybe the solution is to make lossless the default sharp option when the source file is a GIF/has pages?

AlexanderTheGrey avatar Jun 14 '22 21:06 AlexanderTheGrey

When choosing the lossy setting for gif2webp, the same behavior occurs, where the quality is much lower, with obvious artifacting, and the file size is much larger than the original GIF.

Thanks for checking, I agree, this sounds like a libwebp encoder problem. Perhaps you could ask the libwebp maintainers, although I'm unsure how much active development it sees as many of the team are now working on JPEG-XL.

I'd prefer to keep sharp's default output settings constant - it's relatively easy for someone to add their own logic to control these based on the input e.g. by calling metadata() first.

lovell avatar Jun 15 '22 07:06 lovell

Yeah, that's what I ended up doing to conditionally use lossless if the source is animated. It may be good to add some notes to the docs that specify to use WebP lossless if the animated image quality and size are not coming out good (in my case, it took some troubleshooting to find out why the quality and size were coming out bad).

It could be an issue with the animated WebP compression algorithm, which is more efficient when there is more data to create patterns for the compression. If true, it would mean there could be rare cases where the file size is better with lossy (which is the only reason to use lossy, to create a smaller file than lossless), depending on the input

Thanks for the update.

AlexanderTheGrey avatar Jun 15 '22 17:06 AlexanderTheGrey

Closing as this appears to be a WebP thing and I don't think there's anything we can do in sharp to alleviate. Please feel free to reopen if evidence arises to show this isn't the case.

lovell avatar Aug 13 '22 23:08 lovell