javascriptimage-processingtransparencysharp

Sharp.js: Output to Lossless WebP Changes Fully Transparent Pixel Color


I'm writing a script that reads image files, manipulates (resets the color of fully transparent pixels to pure black, crops the images), and writes the exports the output images to the lossless WebP. I'm using the Sharp.js library.

The output image is written from a buffer which is a 1D array of RGBA pixel data (a cropped image). console.log(imgBuffer); gives:
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 19246 more bytes>

console.log(imgBuffer.slice(imgBuffer.length - 50, imgBuffer.length)); gives the last bytes:
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>

Here is the code that write the buffer to an image file:

sharp(imgBuffer, {
    raw: {
      height: bin.height,
      width: bin.width,
      channels: 4
    }})
  .webp({ lossless: true, quality: 100, alphaQuality: 100, force: true })
  .toFile('output.webp');

However, the output image contains "distorted" colors for some of the fully transparent pixels.

Here is an example of an input file. As it is seen, the fully transparent pixels have pure black color (here, I'm using GIMP to manipulate Alpha channel). Input

Here is an example of an output WebP file. As it is seen, the fully transparent pixels have different colors than in the input file. Output

Question: In Sharp.js, how to prevent transparent pixels color change during export?


Solution

  • This looks like an intentional behavior of the library, not an accident/bug.

    Fully transparent pixels are usually allowed to be changed, because they are fully transparent, and changing their color content doesn't change the appearance.

    A common behavior is to automatically "redact" fully transparent areas, because users might expect transparent pixels to have "no color", i.e. image content in such an area to be "gone", unrecoverable.

    If you don't want that, file an issue with the maintainers of the library that wrote the image file. I don't know if Sharp.js has its own image compression. They might use another library for this.