2010-07-30 68 views
12

我有兩個圖像,都與alpha通道。我想把一個圖像放在另一個圖像上,產生一個帶有alpha通道的新圖像,就像在圖層中渲染時一樣。我想用Python Imaging Library來做到這一點,但在其他系統中的建議將會非常棒,即使原始數學也會是一個福音。我可以使用NumPy。使用Python成像庫(PIL),如何在另一個圖像上使用Alpha通道組成圖像?

OVER:

a http://dl.dropbox.com/u/1688099/ennorath/tmp/a.png + b http://dl.dropbox.com/u/1688099/ennorath/tmp/b.png = blend http://dl.dropbox.com/u/1688099/ennorath/tmp/over.png

與之相對BLEND 0.5:

a http://dl.dropbox.com/u/1688099/ennorath/tmp/a.png + b http://dl.dropbox.com/u/1688099/ennorath/tmp/b.png = blend http://dl.dropbox.com/u/1688099/ennorath/tmp/blend.png

+0

這個工作對我來說:im.paste(圖像,盒,面罩) http://stackoverflow.com/questions/5324647/how-to-merge-a-transparant-png-image -with-another-image-using-pil – Gonzo 2011-12-16 14:13:06

回答

15

我無法找到一個alpha composite FUNC重刑在PIL,所以這裏是我與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') 

enter image description here

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

enter image description here

alpha_composite產生:

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

enter image description here

+0

工程就像一個魅力。謝謝。 – 2010-07-31 03:06:28

28

這似乎這樣的伎倆:

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") 
+0

我站在更正:)感謝分享。 – unutbu 2010-07-31 03:11:11

+1

@〜unutbu不,你的效果更好。我已將您的解決方案併入我的項目中。 – 2010-08-02 03:08:20

+1

剛剛嘗試過這一個,並且(a)它工作得非常好,至少對於我正在做的快速和骯髒的任務和(b)不需要安裝numpy。注意上面的評論。 – dpjanes 2011-06-20 11:16:36

19

枕頭2.0現在包含一個alpha_composite功能做到這一點。

img3 = Image.alpha_composite(img1, img2) 
相關問題