thoppe/pixelhouse

Overlaying non-transparent, same-size-as-Canvas images makes them fully transparent

Closed this issue · 2 comments

This issue bounces off of #38

I'm trying to overlay an image the same size as the Canvas object, using the method

with canvas.layer() as layer:
  layer += image.canvas

This works for images that are the same size as the original/base Canvas (16x16), but they're transparent around the edges. When I try and overlay a fully-colored 16x16 image, it returns transparent. This issues was avoided using the black_to_transparent function you wrote for me last time. I'm not sure why.

def black_to_transparent(canvas: ph.Canvas) -> ph.Canvas:
    black_pixels = np.all(canvas.img == [0, 0, 0, 0], axis=-1)
    transparent_canvas = canvas.copy()
    transparent_canvas[~black_pixels, 3] = 255  # Change alpha to 255
    return transparent_canvas

But since you said you've fixed it, I changed it to this:

def black_to_transparent(canvas: ph.Canvas) -> ph.Canvas:
    return canvas

This only causes the full image to go away; it works for everything else.

Here's the full image in question:

town_default

And a working transparent image for reference:

wilds_default

Normal World:

screen1

Bugged world (nevermind the purple guys they're fine. Just notice there's no door sprites):

world_1560191136

Also, the regular black_to_transparent method causes this following sprite to have a white background. I compared it to a working transparent sprite, which still worked fine:

Doesn't work:

null_actor

Works fine:

null_npc

There's probably some issue with how opencv handles transparency. I know that alphas can be infuriating. Thank you.

Again, really excellent bug report! I was able to reproduce it and I'll see if I can apply a fix in a bit. In the meantime as I think I know what the problem is: opencv acts differently when there is/isn't a transparent channel and this is the problem. One really easy way to fix it in the meantime is to set your "door" image to be fully opaque:

door = ph.load("door.png")
door.alpha = 255

Which fixes it for me. I'll see what I can do it infer a fully opaque image when it lacks a transparent channel.

I've pushed a small change to pypi (v 0.5.4) that should fix the issue. By default now, all images are loaded with a fully opaque channel if the alpha channel isn't present. This seems like a much more reasonable default!