关于python:如何使用PIL将透明png图像与另一个图像合并

How to merge a transparent png image with another image using PIL

我有一个透明的png图像"foo.png"
我打开了另一张图片

1
im = Image.open("foo2.png");

现在我需要的是将foo.png与foo2.png合并。

(foo.png包含一些文本,我想在foo2.png上打印该文本)


1
2
3
4
5
6
7
import Image

background = Image.open("test1.png")
foreground = Image.open("test2.png")

background.paste(foreground, (0, 0), foreground)
background.show()

.paste()的第一个参数是要粘贴的图像。第二个是坐标,秘密酱是第三个参数。它表示将用于粘贴图像的蒙版。如果传递具有透明度的图像,则Alpha通道将用作遮罩。

检查文档。


当背景图像还包含透明度时,Image.paste无法正常工作。您需要使用真正的Alpha Compositing。

Pillow 2.0包含一个执行此操作的alpha_composite函数。

1
2
3
4
background = Image.open("test1.png")
foreground = Image.open("test2.png")

Image.alpha_composite(background, foreground).save("test3.png")

编辑:两个图像都必须是RGBA类型。因此,如果它们是调色板等,你需要调用convert('RGBA')。如果背景没有alpha通道,那么你可以使用常规粘贴方法(应该更快)。


正如olt已经指出的那样,当源和目标都包含alpha时,Image.paste无法正常工作。

请考虑以下情形:

两个测试图像,都包含alpha:

enter image description here
enter image description here

1
2
layer1 = Image.open("layer1.png")
layer2 = Image.open("layer2.png")

像这样使用Image.paste合成图像:

1
2
3
final1 = Image.new("RGBA", layer1.size)
final1.paste(layer1, (0,0), layer1)
final1.paste(layer2, (0,0), layer2)

产生下面的图像(重叠的红色像素的alpha部分完全取自第二层。像素未正确混合):

enter image description here

使用Image.alpha_composite合成图像如下:

1
2
3
final2 = Image.new("RGBA", layer1.size)
final2 = Image.alpha_composite(final2, layer1)
final2 = Image.alpha_composite(final2, layer2)

生成以下(正确)图像:

enter image description here


也可以使用混合:

1
2
3
4
im1 = Image.open("im1.png")
im2 = Image.open("im2.png")
blended = Image.blend(im1, im2, alpha=0.5)
blended.save("blended.png")


1
2
3
4
5
def trans_paste(bg_img,fg_img,box=(0,0)):
    fg_img_trans = Image.new("RGBA",bg_img.size)
    fg_img_trans.paste(fg_img,box,mask=fg_img)
    new_img = Image.alpha_composite(bg_img,fg_img_trans)
    return new_img


有一个类似的问题,很难找到答案。使用以下功能可以将具有透明度参数的图像粘贴到特定偏移处的另一个图像上。

1
2
3
4
5
6
7
8
9
10
11
12
import Image

def trans_paste(fg_img,bg_img,alpha=1.0,box=(0,0)):
    fg_img_trans = Image.new("RGBA",fg_img.size)
    fg_img_trans = Image.blend(fg_img_trans,fg_img,alpha)
    bg_img.paste(fg_img_trans,box,fg_img_trans)
    return bg_img

bg_img = Image.open("bg.png")
fg_img = Image.open("fg.png")
p = trans_paste(fg_img,bg_img,.7,(250,100))
p.show()