我有两张图片,都有alpha通道。我想将一个图像放在另一个图像上,从而生成带有alpha通道的新图像,就像它们在图层中呈现一样。我想用Python Imaging Library做到这一点,但是其他系统中的建议会很棒,即使原始数学也是一个好处;我可以使用NumPy。
答案 0 :(得分: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 :(得分:21)
Pillow 2.0现在包含alpha_composite
功能。
img3 = Image.alpha_composite(img1, img2)
答案 2 :(得分:16)
我在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
'''
# http://stackoverflow.com/a/3375291/190597
# http://stackoverflow.com/a/9166671/190597
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')