jimp-dev/jimp

Blitting uses wrong alpha compositing (generates borders)

Open

#1072 opened on Feb 17, 2022

View on GitHub
 (1 comment) (0 reactions) (0 assignees)JavaScript (13,218 stars) (785 forks)batch import
bughelp wantedsolution in issue

Description

Expected Behavior

Currently using jimp in free-tex-packer-core. I started updating the version on npm (https://github.com/astrocreep/free-tex-packer-core) and wanted to update jimp to the current version. after some basic fixes, everything seemed fine, but i discovered some artifacts around my sprites. After digging into this, it looks like alpha compositing in the blit method is calculating wrong values. The atlas is the destination image (new Jimp with background 0x0). And then sprites are blitted onto it. I would expect that every sprite blitted on an 100% transparent image results in a composition of the the source sprites.

Current Behavior

Currently blitting pixels with alpha results in strange mixed colors on the edges

Steps to Reproduce

  1. create a new Jimp image with background 0x0
  2. take a png with a simple white filles circle with alpha borders
  3. blit this onto the jimp image
  4. save it
  5. new image will have grey pixels around the white circle

Context

There is an wikipedia article about alpha compositing: https://en.wikipedia.org/wiki/Alpha_compositing

Using the formulas there fixes the issue:

baseImage.bitmap.data[dstIdx] = ((src.r * src.a / 255) + (dst.r * dst.a * (255 - src.a) / 65025)) / src.a * 255;
baseImage.bitmap.data[dstIdx + 1] = ((src.g * src.a / 255) + (dst.g * dst.a * (255 - src.a) / 65025)) / src.a * 255;
baseImage.bitmap.data[dstIdx + 2] = ((src.b * src.a / 255) + (dst.b * dst.a * (255 - src.a) / 65025)) / src.a * 255;
baseImage.bitmap.data[dstIdx + 3] = src.a + (dst.a * (255 - src.a) / 255);

Contributor guide