liquidev/pan

Blitting image with alpha channel doesn't seem blend alpha

wezm opened this issue · 1 comments

wezm commented

Loading a transparent PNG then blitting it seems to always have a light background instead of blending it with what's already there.

E.g. with this image:

animation { width = 1000, height = 400, length = 1, framerate = 60 }

gitLogo = image.load("Git-Logo-2Color.png")
nearlyblack = solid(hex("#202020"))

function render()
  clear(nearlyblack)
  blit(gitLogo, 0, 0)
end
wezm commented

The issue might be that Cairo's ARGB32 format expects pre-multiplied alpha. However, I'm not sure this is accounted in the image loading function as PNG requires non-pre-multiplied alpha:

pan/src/panpkg/api.nim

Lines 158 to 168 in 6289a27

# convert from RGBA to ARGB because cairo <3
for y in 0..<height:
for x in 0..<width:
let
r = channels * (x + y * width)
g = r + 1
b = g + 1
a = b + 1
(img[r], img[g], img[b], img[a]) =
when cpuEndian == bigEndian: (img[a], img[r], img[g], img[b])
else: (img[b], img[g], img[r], img[a])