我正在将一张图片粘贴到另一张图片上,看了这个问题后,我看到为了粘贴一张transparent图片,你需要做
background = Image.open("test1.png")
foreground = Image.open("test2.png")
background.paste(foreground, (0, 0), foreground)
对于正常图像,你应该做
background = Image.open("test1.png")
foreground = Image.open("test2.png")
background.paste(foreground, (0, 0)) // difference here
我的问题是,如何检查图像是否透明,以便确定如何使用
paste
方法(有或没有最后一个参数)。
我提出了以下函数作为无依赖性解决方案(当然除了 PIL),它以 PIL
Image
对象作为参数:
def has_transparency(img):
if img.info.get("transparency", None) is not None:
return True
if img.mode == "P":
transparent = img.info.get("transparency", -1)
for _, index in img.getcolors():
if index == transparent:
return True
elif img.mode == "RGBA":
extrema = img.getextrema()
if extrema[3][0] < 255:
return True
return False
此函数的工作原理是首先检查图像信息中是否定义了“透明度”属性——如果是,我们返回“True”。然后,如果图像使用索引颜色(例如在 GIF 中),它会获取调色板中透明颜色的索引 (
img.info.get("transparency", -1)
) 并检查它是否在画布中的任何地方使用 (img.getcolors()
)。如果图像处于 RGBA 模式,则推测它具有透明度,但它通过获取每个颜色通道的最小值和最大值 (img.getextrema()
) 进行双重检查,并检查 alpha 通道的最小值是否低于 255。
我使用 numpy 检查 alpha 通道:
def im_has_alpha(img_arr):
'''
returns True for Image with alpha channel
'''
h,w,c = img_arr.shape
return True if c ==4 else False
使用它,假设
pil_im
是你的枕头图片:
import numpy as np
has_transparency = im_has_alpha(np.array(pil_im))
检查 alpha 透明层的图像模式。例如,RGB 没有透明度,但 RGBA 有。
有关更多信息,请参见https://pillow.readthedocs.io/en/latest/handbook/concepts.html。
此功能的工作原理:
def image_is_transparent(image: Image, opaque: int = 255) -> bool:
if 'A' in image.mode:
# see if minimum alpha channel is below opaque threshold
return image.getextrema()[image.mode.index('A')][0] < opaque
if image.mode != 'P' or 'transparency' not in image.info:
# format doesn't support transparency
return False
transparency = image.info['transparency']
colors = image.getcolors()
# check each color in the image
if isinstance(transparency, bytes):
# transparency is one byte per palette entry
for _, index in colors:
if transparency[index] < opaque:
return True
else:
# transparency is palette index of fully transparent
for _, index in colors:
if transparency == index:
return True
return False