Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lossless webp? #962

Open
soadzoor opened this issue Dec 6, 2024 · 9 comments
Open

Lossless webp? #962

soadzoor opened this issue Dec 6, 2024 · 9 comments
Assignees

Comments

@soadzoor
Copy link

soadzoor commented Dec 6, 2024

First of all, I'd like to thank you for this awesome project, it solved a problem I've had for years with node-canvas: mozilla/pdf.js#17188

I know the current version is at pre-release stage, although I'd like to report something, which I think is already "checked" on the roadmap, although I don't think it's actually finished completely.

canvas.toBuffer("image/webp", 100) is not working perfectly. First of all, it's not very obvious what should happen when I provide 100 for quality. Does the image become a lossless webp format in this case? Or it's still lossy with a large filesize?

Based on my tests, I've found that when I use image/webp, it's significantly slower than if I use image/png (about 18% slower), and the filesize produced by it it significantly larger - it produces around 73% larger files compared to when I use imagemin-webp

Can we somehow improve these things in the future?

@Brooooooklyn Brooooooklyn self-assigned this Dec 6, 2024
@Brooooooklyn
Copy link
Owner

canvas.toBuffer("image/webp", 100)

Yes, this is lossless

Based on my tests, I've found that when I use image/webp, it's significantly slower than if I use image/png (about 18% slower)

With same quality?

it produces around 73% larger files compared to when I use imagemin-webp

The same quality or less quality with imagemin-webp?

@soadzoor
Copy link
Author

soadzoor commented Dec 6, 2024

With same quality?
png is always lossless. I don't think "quality" makes sense when it comes to "lossless" formats.
The same quality or less quality with imagemin-webp?
I'm using lossless option for imagemin-webp, and it that case, the quality "number" is ignored, I believe. This is how I use it:

await imagemin([`${source}/*.png`], {
	destination: destination,
	plugins: [
		imageminWebp({
			lossless: true,
		}),
	],
});

By the way, I just realized the quality shouldn't be 100, because the valid range is between 0 and 1 (at least in mozilla's documentation for HTMLCanvas). However, changing it from 100 to 1 in @napi-rs/canvas significantly reduces the filesize, but the quality is also compromised.

So I guess you're using the range between 0 and 100? Shouldn't that be consistent with the browser's canvas and set it between 0 and 1?

@Brooooooklyn
Copy link
Owner

So I guess you're using the range between 0 and 100? Shouldn't that be consistent with the browser's canvas and set it between 0 and 1?

toBuffer is not a standard API, so I think the range between 0-100 is okay.

I will investigate why there is a difference in speed and size

@soadzoor
Copy link
Author

soadzoor commented Dec 6, 2024

Thanks!

@Brooooooklyn
Copy link
Owner

What system and CPU are you using for test? On my MacBook Pro, the webp is faster than png

CleanShot 2024-12-07 at 00 09 28@2x

@soadzoor
Copy link
Author

soadzoor commented Dec 6, 2024

What system and CPU are you using for test? On my MacBook Pro, the webp is faster than png

CleanShot 2024-12-07 at 00 09 28@2x

Wow, that's interesting!

I'm using an i5 7600-K CPU on an Ubuntu 22 system. I can try on windows as well, give me a few minutes.

@soadzoor
Copy link
Author

soadzoor commented Dec 6, 2024

Probably I was wrong... Not exactly sure how, but I swear, the first time I tried, I measured 15% slower times with webp than with png. Now it seems to be the other way around, webp is indeed faster. Both on Ubuntu and windows. Just for the record:
On ubuntu I measured:
png: 187.152ms
webp: 165.804ms

On windows I measured:
png: 200.008ms
webp: 184.93ms

The hardware is the same for both of these.

So I guess the only remaining issue is the filesize, which is - for some reason - a lot smaller when I use imagemin

Thank you for your quick feedbacks @Brooooooklyn

@Brooooooklyn
Copy link
Owner

The underlying webp encoder in this library is libwebp, the same with underlying library in imagemin-webp: https://github.com/imagemin/imagemin-webp/blob/main/index.js

The size differences come from the imagemin-webp call the cwebp under the hood and it would apply 75 quality factor to the original webp: https://github.com/webmproject/libwebp/blob/main/examples/cwebp.c#L548
Which means whatever your input webp images are optimized, it would be smaller after processed by imagemin-webp

@soadzoor
Copy link
Author

@Brooooooklyn I'm a bit confused. 75 quality would mean it's NOT lossless, right? But then, how is it still lossless?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants