如何使用Python Imaging Library(PIL)将带有Alpha通道的图像合成到另一张图像上?

17

我有两张带有alpha通道的图片。我想将其中一张叠加到另一张图片上,得到一张新的带有alpha通道的图片,就像在图层中渲染一样。我想使用Python Imaging Library实现这个功能,但是其他系统的建议也很棒,甚至原始的数学公式也会有帮助;我可以使用NumPy。


这对我有用:im.paste(image, box, mask)https://dev59.com/xm435IYBdhLWcg3wlRMf - Gonzo
3个回答

31

这似乎可以解决问题:

from PIL import Image
bottom = Image.open("a.png")
top = Image.open("b.png")

r, g, b, a = top.split()
top = Image.merge("RGB", (r, g, b))
mask = Image.merge("L", (a,))
bottom.paste(top, (0, 0), mask)
bottom.save("over.png")

1
@~unutbu 不,您的更好。我已经将您的解决方案纳入我的项目中了。 - Kris Kowal
1
刚试了一下,(a)它的表现相当不错,至少对于我正在进行的快速任务来说是这样的,(b)它不需要安装numpy。不过请注意上面的评论。 - dpjanes

25

Pillow 2.0现在包含了一个 alpha_composite 函数来实现这个功能。

img3 = Image.alpha_composite(img1, img2)

18

我在PIL中找不到一个alpha composite函数,所以这里是我尝试使用numpy实现它的代码:

import numpy as np
from PIL import Image

def alpha_composite(src, dst):
    '''
    Return the alpha composite of src and dst.

    Parameters:
    src -- PIL RGBA Image object
    dst -- PIL RGBA Image object

    The algorithm comes from http://en.wikipedia.org/wiki/Alpha_compositing
    '''
    # https://dev59.com/-HA75IYBdhLWcg3wS29A#3375291
    # https://dev59.com/nmox5IYBdhLWcg3wf0bl#9166671
    src = np.asarray(src)
    dst = np.asarray(dst)
    out = np.empty(src.shape, dtype = 'float')
    alpha = np.index_exp[:, :, 3:]
    rgb = np.index_exp[:, :, :3]
    src_a = src[alpha]/255.0
    dst_a = dst[alpha]/255.0
    out[alpha] = src_a+dst_a*(1-src_a)
    old_setting = np.seterr(invalid = 'ignore')
    out[rgb] = (src[rgb]*src_a + dst[rgb]*dst_a*(1-src_a))/out[alpha]
    np.seterr(**old_setting)    
    out[alpha] *= 255
    np.clip(out,0,255)
    # astype('uint8') maps np.nan (and np.inf) to 0
    out = out.astype('uint8')
    out = Image.fromarray(out, 'RGBA')
    return out

例如,给定以下这两张图片:

img1 = Image.new('RGBA', size = (100, 100), color = (255, 0, 0, 255))
draw = ImageDraw.Draw(img1)
draw.rectangle((33, 0, 66, 100), fill = (255, 0, 0, 128))
draw.rectangle((67, 0, 100, 100), fill = (255, 0, 0, 0))
img1.save('/tmp/img1.png')

在这里输入图片描述

img2 = Image.new('RGBA', size = (100, 100), color = (0, 255, 0, 255))
draw = ImageDraw.Draw(img2)
draw.rectangle((0, 33, 100, 66), fill = (0, 255, 0, 128))
draw.rectangle((0, 67, 100, 100), fill = (0, 255, 0, 0))
img2.save('/tmp/img2.png')

在此输入图片描述

alpha_composite 产生以下结果:

img3 = alpha_composite(img1, img2)
img3.save('/tmp/img3.png')

输入图像描述


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