5

I'm struggling a touch with pasting one image with a transparent background on another, also with a transparent background, with the right alpha/colour blending.

Here are some example images, red.png and blue.png:

red.png blue.png

I want to paste blue.png on top of red.png, and achieve this effect:

Expected Result

That image was made by combining the two images in Photoshop, simply as two layers.

The closest I can get using the Python Imaging Library is:

Actual Result

with this code:

from PIL import Image

blue = Image.open("blue.png")
red = Image.open("red.png")
red.paste(blue, (0,0), blue)
red.save("result.png")

Do you see how the alpha and the colour is off where the two circles overlap? In the expected result image, the red and blue blends together in a purplish way, but there's an unwanted alpha halo in the actual result image.

How can I achieve my ideal result in PIL?

4

3 回答 3

3

我得到的最接近的是使用此处找到的 alpha_composite 函数。效果真的很好!

于 2013-10-25T09:43:48.823 回答
1

我通常使用 numpy/scipy 来完成图像处理任务,尽管我的第一次体验(很好)是使用 PIL。因此,我不确定以下内容是否能满足您的需求。

给定一个特定的 pixel1,alpha1 来自 image1,pixel2 和 alpha2,来自 image2,outputPixel 将如下所示。

alpha1>=alpha2 then outputPixel = (alpha1-alpha2)*pixel1 + alpha2*pixel2
alpha1==alpha2 then outputPixel = 0*pixel1 + alpha2*pixel2 note in this case alpha1-alpha2 equals 0
alpha1<alpha2 then outputPixel = 0*pixel1 + alpha2*pixel2

使用上述定义,我们将基本上计算第一张图像对每个像素的贡献,然后在应用其 alpha 贴图后将其添加到第二张图像

我们也可以直接从 imshow 获取

r1 = scipy.misc.imread('red.png')
b1 = scipy.misc.imread('blue.png')
r1 = r1.astype(numpy.float32)
b1 = b1.astype(numpy.float32)

alpha1 = r1[:,:,3]
alpha2 = b1[:,:,3]

#scale the alpha mattes to keep resulting alpha'd images in display range
alpha1Scaled = alpha1 / 255
alpha2Scaled = alpha2 / 255
diff1 = alpha1Scaled - alpha2Scaled

i1 = r1[:,:,0:3]
i2 = b1[:,:,0:3]
#create the alpha mapped images
d1 = numpy.zeros(i1.shape)
d2 = numpy.zeros(i2.shape)
for z in range(3):
    d1[:,:,z] =(diff1>=0)*diff1*i1[:,:,z] 
    d2[:,:,z] = i2[:,:,z]*alpha2Scaled

#belend the result
result = d1 + d2

#rescale in case of overflow
resultScaled = 255*(result/result.max())

#to display 
imshow(( resultScaled  ).astype(uint8))
show()

#note the below gives us the same result
figure()
imshow(red)
imshow(blue)
show()
于 2013-10-24T16:17:42.437 回答
0

使用 blend() 重叠两个图像。下面的代码重叠文件夹中的图像。您可以更改 alpha 的值以获得完美的混合

listing = os.listdir("images2/")
alpha = 2.0 
for file in listing:
    im = Image.open(path1 + file)  
    new_img = Image.blend(im, new_img, alpha) 
new_img.save("new008.png","PNG")
于 2017-05-18T22:14:38.150 回答