Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Produce a composed image with different sized layers with transparency

I'm very new to Python and am exploring it's use to allow users to build custom images. The idea is that the client would select a few options and the image would be created on the server then downloaded (or used for other things on the server side).

The image is composed of many images, most of which are small icon type of images that are irregular shapes and have transparency. All layers are .png files.

I've tried using Pillow but it seems the image needs to be the same size as the overall image to properly use the transparency of the top layers.

Here's what I've tried so far:

from PIL import Image

background = Image.open("Background.png")
foreground = Image.open("Trim.png")
fire = Image.open("Type_Fire_Large.png")

background = Image.alpha_composite(background, foreground)
background.paste(fire, (150, 150))
background.show()

The image looks like this:

Layered image with black on overlay

Background.png is the shaded "noise" and Trim.png is the grey diagonal lines. The best part: Trim.png has the center transparent and is able to show Background.png in the middle. But it's also the same size as the image.

The problem is Fire; notice how theres that black border (and odd fuchsia dot). The documentation states that the overlay image needs to be the same size. But it seems like a common scenario where someone would want to place a smaller icon with transparency on top of another image and compose them into one image.

I'm not attached to any particular library, I'm wide open to ideas and alternatives. The only thing I'm trying to do is keep it simple, so creating an entire game engine or the like to produce an image would probably be too much.

like image 321
Chris Avatar asked Feb 28 '17 03:02

Chris


2 Answers

To just paste one png on top of another, respecting transparency, try

background.paste(fire, (x,y), fire.convert("RGBA"))
like image 62
Johannes Holmberg Avatar answered Nov 09 '22 05:11

Johannes Holmberg


First I'd say Johannes Holmberg already answered your main concern: The missing transparency.

But I can hopefully explain what it's about with that odd fuchsia dot:

A transparent color image is usually stored as RGBA (RGB for Red, Green, Blue and A for Alpha). Here Alpha defines the transparency, from no transparency to full transparency.

Overlaying the images the correct way we see the GIMP Logo but the color stripe is almost invisible - because it's (almost) transparent.

Using RGBA

But - as every pixel could be possibly visible - every pixel does still have a color. Even those pixels with 100% transparency. Thus, if we do not take Alpha into consideration we see each pixel color without transparency. This way we might have disturbing colors that are usually not disturbing at all - as long as they are fully transparent.

enter image description here

like image 2
RuDevel Avatar answered Nov 09 '22 07:11

RuDevel