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

时间:2011-03-16 11:34:00

标签: python image image-processing python-imaging-library

我有一个透明的png图片“foo.png” 我用

打开了另一张图片
im = Image.open("foo2.png");

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

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

7 个答案:

答案 0 :(得分:227)

import Image

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

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

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

检查docs

答案 1 :(得分:55)

当背景图片还包含透明度时,

Image.paste无法正常工作。您需要使用真实Alpha Compositing

Pillow 2.0包含alpha_composite功能。

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

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

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

答案 2 :(得分:38)

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

考虑以下情况:

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

enter image description here enter image description here

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

使用Image.paste合成图像,如下所示:

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

生成以下图像(叠加红色像素的alpha部分完全取自第2层。像素未正确混合):

enter image description here

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

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

生成以下(正确)图像:

enter image description here

答案 3 :(得分:7)

还可以使用混合:

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

答案 4 :(得分:1)

我最终自己编码了用户@ P.Melch提出的this comment的建议,并由@Mithril在我正在进行的项目中提出了建议。

我也编码了here's the code for it,超出了安全范围。 (我链接了一个特定的提交,因为在此存储库的将来情况可能会发生变化)

注意:我希望像np.array(Image.open(...))这样的图像中有numpy数组作为copy_from的输入A和B以及此链接函数overlay的参数。

依赖项是它之前的函数,copy_from方法和numpy数组作为要切片的PIL图像内容。

尽管文件是面向类的,但是如果您想使用该功能overlay_transparent,请确保将self.frame重命名为背景图像numpy数组。

或者您可以只复制整个文件(可能删除一些导入和Utils类)并与Frame类进行交互,如下所示:

# Assuming you named the file frame.py in the same directory
from frame import Frame

background = Frame()
overlay = Frame()

background.load_from_path("your path here")
overlay.load_from_path("your path here")

background.overlay_transparent(overlay.frame, x=300, y=200)

然后,将background.frame作为覆盖和alpha合成数组,可以使用overlayed = Image.fromarray(background.frame)或类似的东西从中获取PIL图像:

overlayed = Frame()
overlayed.load_from_array(background.frame)

或者只是background.save("save path"),因为它直接取自Alpha复合内部self.frame变量。

您可以读取文件并通过我编码的该实现找到其他不错的功能,例如方法get_rgb_frame_arrayresize_by_ratioresize_to_resolutionrotate,{{1} },gaussian_blurtransparency:)

您可能希望删除该项目专用的vignetting方法。

很高兴能为您提供帮助,请务必查看我所谈论的project的仓库,此问题和线索对我的发展大有帮助:)

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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