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
WebP compression artefacts relating to premultiplication rounding #3658
Comments
Please can you provide a complete, standalone code sample that allows someone else to reproduce the problem you are experiencing as I'd like to understand this first before jumping into a solution. |
Here's sample code and the input image to reproduce the issue. The two outputs to compare are from v0.32.1 and v0.31.3. Although I have singled out the above mentioned commit to be the culprit by recompiling v0.32.1 with only that change reverted in Note: You may have to zoom in a little into the outputs to see the distorted pixels.
Input image: textsample.png |
These look like WebP compression artefacts. For WebP output images that contain text, I recommend using either |
Yes, the artefacts seem to be limited to WebP encoding only. But even for WebP encoding, they did appear only after the premultiplication change. As for conditionally using Which is why making integer premultiplication configurable seems to be the only solution for us. |
Does increasing the https://sharp.pixelplumbing.com/api-output#webp If not, this might provide a good test image (as a PNG, without the artefacts) to use to ask the libwepb maintainers upstream. |
Yes. Increasing quality and using Please confirm if my understanding is correct - With everything else being the same, we get the better output without premultiplication rounding vs with premultiplication rounding. That means the upstream library is producing consistent results. If the above is true, wouldn't it be better to make premultiplication rounding configurable behind an option with the default value set to |
If libwebp is introducing compression artefacts then that feels like the right place to address this if possible. What did the libwebp maintainers say when you asked them? |
I haven't asked them because without sharp's premultiplication rounding, libwebp is producing the artefact-free output. And since the rounding was introduced in sharp, I thought this would be the right place to ask. Also, was this rounding change expected to be completely harmless across different combinations w/ resize()? I am trying to understand the reasoning behind incorporating this change across the board without the option to go back. At this point, taking this up with libwebp maintainers may or may not solve the issue. But allowing to opt-out of the rounding within sharp will definitely fix it. |
The output of your sample code, saved as a lossless PNG, does not appear to have the compression artefacts: Using this PNG without artefacts as input via the libwebp command line tools (and not sharp):
...produces an output image with compression artefacts: The intermediate WebP image is attached here in a zip file so GitHub doesn't mangle it. A small change to rounding behaviour in sharp has allowed the creation of a PNG image that can then be used to expose these compression artefacts. It is likely that other input images, those that have not been processed via sharp, will also expose this behaviour of libwebp. If inter-pipeline precision within sharp is of concern, I recommend you take a look at pipelineColourspace. |
I hope this information helped. Please feel free to re-open with more details if further assistance is required. |
Feature request
What are you trying to achieve?
The recent change related to (un)premultiplication in resize() is producing artefacts in one of our images (messing up color in some pixels) when resize() + extend() is applied on it. It is a 158 x 31 image; a word of text on a fully transparent background, all letters having the same darg-gray (#333333) color. I verified this change to be the cause by reverting it and rebuilding sharp, and applying the resize again.
We would love to have an option added to the resize() operation to go back to not using integer (un)premultiplication. I would be happy to contribute with a PR. Just wanted to collect thoughts first.
When you searched for similar feature requests, what did you find that might be related?
NA
What would you expect the API to look like?
A new field
useIntegerPremultiply
added to resize(). Will default totrue
:The text was updated successfully, but these errors were encountered: