使用PIL将背景和透明图像合并

6

我有一个PNG格式的背景图片,想要在该图片上添加透明的网格线,但是效果并不如预期。当我在网格线上应用透明度时,背景图片上相应的区域也变成了透明色。

我的操作如下:

from PIL import Image, ImageDraw

map_background = Image.open(MAP_BACKGROUND_FILE).convert('RGBA')
map_mesh = Image.new('RGBA', (width, height), (0, 0, 0, 0))
draw = ImageDraw.Draw(map_mesh)

# Create mesh using: draw.line([...], fill=(255, 255, 255, 50), width=1)
...

map_background.paste(map_mesh, (0, 0), map_mesh)

但是结果是: enter image description here 如果你仔细看,你会看到一个象棋板图案(在图形程序中用作无背景)。透明线使得背景层在两个层相遇的地方也变成了透明。但是我只想在背景上面添加透明线。
我可以用以下方法解决:
map_background.paste((255,255,255), (0, 0), map_mesh)

但是,由于我对不同的线使用不同的颜色,因此我必须为每种颜色进行此过程。如果我有100种颜色,那么我需要100个图层,这并不是一个很好的解决方案。


可能是 https://dev59.com/xm435IYBdhLWcg3wlRMf 的重复问题。 - Charles Merriam
2个回答

11
你想要做的是把网格与背景合成在一起,为此你需要使用 Image.blend 或者 Image.composite。以下是一个使用后者将随机 Alpha 值的红色线条合成到白色背景上的示例:
import Image, ImageDraw, random
background = Image.new('RGB', (100, 100), (255, 255, 255))
foreground = Image.new('RGB', (100, 100), (255, 0, 0))
mask = Image.new('L', (100, 100), 0)
draw = ImageDraw.Draw(mask)
for i in range(5, 100, 10):
    draw.line((i, 0, i, 100), fill=random.randrange(256))
    draw.line((0, i, 100, i), fill=random.randrange(256))
result = Image.composite(background, foreground, mask)
从左到右:
 [背景]        [遮罩]          [前景]          [结果]

背景 遮罩 前景 复合

(如果你想将结果写回到背景图像中,那么可以使用Image.paste的其中一个带遮罩版本,正如Paulo Scardine在已删除的答案中指出的。)


左侧有一个看不见的白色。 - sngjuk

0

我在尝试上述示例时遇到了一些问题。相反,以下方法对我有效:

import numpy as np
import Image
import ImageDraw

def add_craters(image, craterization=20.0, width=256, height=256):

    foreground = Image.new('RGBA', (width, height), (0, 0, 0, 0))
    draw = ImageDraw.Draw(foreground)

    for c in range(0, craterization):
        x = np.random.randint(10, width-10)
        y = np.random.randint(10, height-10)
        radius = np.random.randint(2, 10)
        dark_color = (0, 0, 0, 128)
        draw.ellipse((x-radius, y-radius, x+radius, y+radius), fill=dark_color)

    image_new = Image.composite(foreground, image, foreground)
    return image_new

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