[英]How to merge a transparent png image with another image using Scikit-image
[英]How to merge a transparent png image with another image using PIL
我有一个透明的 png 图像foo.png
并且我打开了另一个图像:
im = Image.open("foo2.png")
现在我需要的是将foo.png
与foo2.png
合并。
( foo.png
包含一些文本,我想在foo2.png
上打印该文本)
from PIL import Image
background = Image.open("test1.png")
foreground = Image.open("test2.png")
background.paste(foreground, (0, 0), foreground)
background.show()
.paste()
第一个参数是要粘贴的图像。 第二个是坐标,秘方是第三个参数。 它表示将用于粘贴图像的蒙版。 如果您传递具有透明度的图像,则 Alpha 通道将用作遮罩。
检查 文档。
当背景图像也包含透明度时, Image.paste
无法按预期工作。 您需要使用真正的Alpha 合成。
Pillow 2.0 包含执行此操作的alpha_composite
函数。
background = Image.open("test1.png")
foreground = Image.open("test2.png")
Image.alpha_composite(background, foreground).save("test3.png")
编辑:两个图像都需要是 RGBA 类型。 所以你需要调用convert('RGBA')
如果它们是调色板等等。如果背景没有 alpha 通道,那么你可以使用常规的 paste 方法(应该更快)。
正如olt已经指出的那样,当源和目标都包含 alpha 时, Image.paste
无法正常工作。
考虑以下场景:
两个测试图像,都包含 alpha:
layer1 = Image.open("layer1.png")
layer2 = Image.open("layer2.png")
使用Image.paste
合成图像, Image.paste
所示:
final1 = Image.new("RGBA", layer1.size)
final1.paste(layer1, (0,0), layer1)
final1.paste(layer2, (0,0), layer2)
生成以下图像(覆盖的红色像素的 alpha 部分完全取自第二层。像素未正确混合):
使用Image.alpha_composite
合成图像, Image.alpha_composite
所示:
final2 = Image.new("RGBA", layer1.size)
final2 = Image.alpha_composite(final2, layer1)
final2 = Image.alpha_composite(final2, layer2)
产生以下(正确的)图像:
还可以使用混合:
im1 = Image.open("im1.png")
im2 = Image.open("im2.png")
blended = Image.blend(im1, im2, alpha=0.5)
blended.save("blended.png")
有一个类似的问题,很难找到答案。 以下函数允许您将具有透明度参数的图像粘贴到另一个图像上的特定偏移量。
import Image
def trans_paste(fg_img,bg_img,alpha=1.0,box=(0,0)):
fg_img_trans = Image.new("RGBA",fg_img.size)
fg_img_trans = Image.blend(fg_img_trans,fg_img,alpha)
bg_img.paste(fg_img_trans,box,fg_img_trans)
return bg_img
bg_img = Image.open("bg.png")
fg_img = Image.open("fg.png")
p = trans_paste(fg_img,bg_img,.7,(250,100))
p.show()
def trans_paste(bg_img,fg_img,box=(0,0)):
fg_img_trans = Image.new("RGBA",bg_img.size)
fg_img_trans.paste(fg_img,box,mask=fg_img)
new_img = Image.alpha_composite(bg_img,fg_img_trans)
return new_img
我最终对用户@P.Melch 提出的这条评论的建议进行了编码,并由@Mithril 在我正在从事的一个项目中提出建议。
我也对越界安全进行了编码,这是它的代码。 (我链接了一个特定的提交,因为这个存储库的未来可能会发生变化)
注意:我希望像np.array(Image.open(...))
这样的图像中的 numpy 数组作为copy_from
的输入 A 和 B 以及此链接函数overlay
参数。
依赖项是它之前的函数、 copy_from
方法和 numpy 数组作为用于切片的 PIL Image 内容。
尽管该文件非常面向类,但如果您想使用该函数overlay_transparent
,请务必将self.frame
重命名为您的背景图像 numpy 数组。
或者你可以复制整个文件(可能会删除一些导入和Utils
类)并与这个 Frame 类交互,如下所示:
# Assuming you named the file frame.py in the same directory
from frame import Frame
background = Frame()
overlay = Frame()
background.load_from_path("your path here")
overlay.load_from_path("your path here")
background.overlay_transparent(overlay.frame, x=300, y=200)
然后你有你的background.frame
作为覆盖和 alpha 合成数组,你可以从它使用overlayed = Image.fromarray(background.frame)
或类似的东西获取 PIL 图像:
overlayed = Frame()
overlayed.load_from_array(background.frame)
或者只是background.save("save path")
因为它直接从 alpha 合成的内部self.frame
变量中获取。
您可以读取该文件,并找到其它的一些功能,这个实现我喜欢编码方法get_rgb_frame_array
, resize_by_ratio
, resize_to_resolution
, rotate
, gaussian_blur
, transparency
, vignetting
:)
您可能希望删除resolve_pending
方法,因为它特定于该项目。
很高兴如果我帮助了你,一定要查看我正在谈论的项目的 repo,这个问题和线程对我的开发帮助很大:)
关键代码是:
_, _, _, alpha = image_element_copy.split()
image_bg_copy.paste(image_element_copy, box=(x0, y0, x1, y1), mask=alpha)
完整的功能是:
def paste_image(image_bg, image_element, cx, cy, w, h, rotate=0, h_flip=False):
image_bg_copy = image_bg.copy()
image_element_copy = image_element.copy()
image_element_copy = image_element_copy.resize(size=(w, h))
if h_flip:
image_element_copy = image_element_copy.transpose(Image.FLIP_LEFT_RIGHT)
image_element_copy = image_element_copy.rotate(rotate, expand=True)
_, _, _, alpha = image_element_copy.split()
# image_element_copy's width and height will change after rotation
w = image_element_copy.width
h = image_element_copy.height
x0 = cx - w // 2
y0 = cy - h // 2
x1 = x0 + w
y1 = y0 + h
image_bg_copy.paste(image_element_copy, box=(x0, y0, x1, y1), mask=alpha)
return image_bg_copy
上述功能支持:
这是我的代码,用于合并 2 个不同大小的图像,每个图像都具有透明度和偏移量:
from PIL import Image
background = Image.open('image1.png')
foreground = Image.open("image2.png")
x = background.size[0]//2
y = background.size[1]//2
background = Image.alpha_composite(
Image.new("RGBA", background.size),
background.convert('RGBA')
)
background.paste(
foreground,
(x, y),
foreground
)
background.show()
这个片段是先前答案的混合,在处理具有不同大小的图像时将元素与偏移混合在一起,每个图像都具有透明度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.