Blitting uses wrong alpha compositing (generates borders)
#1072 opened on Feb 17, 2022
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
- create a new Jimp image with background 0x0
- take a png with a simple white filles circle with alpha borders
- blit this onto the jimp image
- save it
- 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);