使用透明度不同的多个大小图层来生成一张合成图像。

11

我对Python非常陌生,正在探索它的用法来允许用户构建自定义图像。想法是客户端会选择一些选项,然后在服务器上创建图像,然后下载(或在服务器端用于其他事情)。

该图像由许多图像组成,其中大部分是小图标类型的不规则形状图像,并具有透明度。所有图层都是.png文件。

我尝试使用Pillow,但似乎顶层透明性需要与整个图像大小相同才能正确使用。

到目前为止,我尝试过:

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()

这张图片看起来像这样:

具有叠加黑色的分层图像

Background.png 是有阴影的“噪点”,Trim.png 是灰色的对角线。最棒的是:Trim.png 中心是透明的,并且能够在中间显示Background.png。但它也与图像的大小相同。

问题在于 Fire;注意到有那个黑边框(和奇怪的紫红色圆点)。文档说明覆盖图像需要与原图相同大小。但这似乎是一个常见的场景,即有人想要将一个更小、带透明度的图标放在另一幅图像上方,并将它们组合成一幅图像。

我没有固定使用任何特定库,我完全开放思路和其他选择。我唯一尝试做的就是保持简单,因此创建整个游戏引擎之类的东西来生成图像可能会太过复杂。

2个回答

7

如果您想将一个PNG图像叠加到另一个PNG图像上,并保留透明度,请尝试以下方法:

background.paste(fire, (x,y), fire.convert("RGBA"))

1
那真是出乎意料的容易,而且有点没有文档记录。谢谢! - Chris
奇怪的紫红色点表明PNG已经处于RGBA模式,你是如何发现这一点的? - Mark Ransom
@MarkRansom,我刚刚对带有Alpha通道的PNG图像执行了Image.open()操作,并注意到在将其用作掩码之前仍然需要进行RGBA转换。 - Johannes Holmberg
PNG 有两种风格,一种是调色板式,一种是真彩色。只需要将调色板式转换为 RGBA。通常,调色板式 PNG 只有一个透明颜色,就像 GIF 一样。这就是我感到惊讶的原因。 - Mark Ransom
@MarkRansom 这是一个有效的观点,我们实际上并不知道转换是否必要。不过,从原始帖子中的图像来看,我猜它们不是真彩色格式,因为那样会很浪费。 - Johannes Holmberg
如果您的图像已经处于RGB模式,您可以使用img.paste(newImg.convert("RGB"), (0, 0), newImg)。 - L0laapk3

2

首先,我想说Johannes Holmberg已经回答了您的主要问题:缺少透明度。

但是,我希望用那个奇怪的品红色点来解释一下它的含义:

透明的彩色图像通常存储为RGBA(RGB代表红、绿、蓝,A代表Alpha)。这里Alpha定义了从完全不透明到完全透明的透明度。

正确叠加这些图像后,我们看到GIMP Logo,但是彩色条纹几乎看不见,因为它(几乎)是透明的。

使用RGBA

但是-由于每个像素都有可能可见- 每个 像素仍然具有颜色。即使是具有100%透明度的那些像素也是如此。因此,如果我们不考虑Alpha,我们会看到每个像素的颜色,而没有透明度。这样,我们可能会看到一些通常不会引起干扰的混合颜色,只要它们是完全透明的。

输入图像描述


这个点让我想起了曾经玩Duke Nukem 3D时,他们在2D精灵中使用紫红色作为要去除的颜色。即使它们是透明的,有一个颜色也是有意义的。我猜这个点可能是保存的一部分,或者在我将其变成透明之前就是那个颜色。感谢澄清,现在我知道了! - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接