sharp
sharp copied to clipboard
Weird artifacts when encoding PNG
Possible bug
Is this a possible bug in a feature of sharp, unrelated to installation?
- [x] Running
npm install sharp
completes without error. - [x] Running
node -e "require('sharp')"
completes without error.
Are you using the latest version of sharp?
- [x] I am using the latest version of
sharp
as reported bynpm view sharp dist-tags.latest
.
What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp
?
System:
OS: Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor
Memory: 14.05 GB / 31.28 GB
Container: Yes
Shell: 5.1.16 - /bin/bash
Binaries:
Node: 20.5.1 - /usr/bin/node
npm: 9.8.0 - /usr/bin/npm
npmPackages:
sharp: ^0.33.3 => 0.33.3
What are the steps to reproduce?
Encode the below file as a PNG with quality 85:
It will result in the following file:
As you can see, there are some weird triangle artifacts at the bottom. Increasing the quality to 86 seems to completely remove those artifacts.
Here's a JS snippet that just does that:
const axios = require('axios');
const sharp = require('sharp');
const fs = require('fs');
(async () => {
// Get the clear-text URL.
const url = 'https://cdn.csgoskins.gg/public/images/floats/v2/p90-death-grip/0.png';
const response = await axios.get(url, {
responseType: 'arraybuffer',
});
const originalFileBuffer = Buffer.from(response.data, 'utf8');
const newFileBuffer = await sharp(originalFileBuffer)
.toFormat('png', {
quality: 85,
})
.toBuffer();
fs.writeFileSync('output.png', newFileBuffer);
})();
https://sharp.pixelplumbing.com/api-output#png
[options.quality]
use the lowest number of colours needed to achieve given quality, setspalette
totrue
[options.palette]
quantise to a palette-based image with alpha transparency support
When quality
is set, palette
is also selected and therefore you have chosen to use a lossy, quantised output.
Ah, I see. I understand that it's a lossy output, but the output from my example is still very unexpected for me. The background color is a single color, and it just adds a completely different color but just in some areas. Is this the desired/expected functionality?
Is there any way to prevent this from happening while still setting a quality
?
The prebuilt binaries provided by sharp include the BSD-licenced libimagequant v2.4.1 for generating and mapping image palettes.
You may have some luck building your own libvips from source compiled with support for an alternative quantisation library such as a more recent GPL-licenced libimagequant or quantizr, but this is left as an exercise for the reader.
Thanks! I ended up setting dither
to 0.0
, which seems to fix the issue in all instances I tested. To your knowledge, should this reliably fix the issue?
Ah yes, this does look like dithering gone a bit wrong, so altering the dither
level until you find a value that works for the type of input you'll be processing is definitely a good idea.
I hope this information helped. Please feel free to re-open with more details if further assistance is required.