PIL:叠加具有不同尺寸和纵横比的图像
PIL: overlaying images with different dimensions and aspect ratios
我一直在尝试叠加 python 中的两个图像以匹配坐标,左上角和右下角具有相同的坐标,并且它们的外观几乎相同,只有几个像素。虽然是不同的分辨率。
使用PIL我已经能够叠加图像,虽然在叠加它们之后图像输出是正方形但分辨率是背景图像的分辨率,前景图像也被错误地重新调整大小(据我所知看)。我一定是做错了什么。
import Image
from PIL import Image
#load images
background = Image.open('ndvi.png')
foreground = Image.open('out.png')
#resizing
foreground.thumbnail((643,597),Image.ANTIALIAS)
#overlay
background.paste(foreground, (0, 0), foreground)
#save
background.save("overlay.png")
#display
background.show()
当将图像放入像 powerpoint 这样可怕的东西时,图像方面几乎完全相同。我已经包含了一个示例图像,左边的图像是我的手动叠加层,右边的图像是 python 的输出。代码中某些点的背景被垂直挤压,也影响了覆盖。我希望能够在 python 中执行此操作并使它看起来像左手图像一样正确。
前期解决方案。
背景图片
width/height/ratio: 300 / 375 / 0.800
前景图片
width/height/ratio: 400 / 464 / 0.862
叠加
from PIL import Image
imbg = Image.open("bg.png")
imfg = Image.open("fg.png")
imbg_width, imbg_height = imbg.size
imfg_resized = imfg.resize((imbg_width, imbg_height), Image.LANCZOS)
imbg.paste(imfg_resized, None, imfg_resized)
imbg.save("overlay.png")
讨论
您在问题中提供的最重要的信息是:
- 前景和背景图片的纵横比不相等,但相似
- 两张图片的左上角和右下角最后需要对齐。
从这些点得出的结论是:其中一张图片的纵横比必须改变。这可以通过 resize()
方法实现(而不是 thumbnail()
,如下所述)。总而言之,目标就是:
将尺寸较大的图像(前景图像)调整为较小背景图像的精确尺寸。即不一定保持前景图片的纵横比。
这就是上面的代码所做的。
对您的方法的两条评论:
首先,我推荐使用最新版本的Pillow(Pillow是PIL的延续项目,它是API兼容的)。在 2.7 版本中 they have largely improved the image re-scaling quality. The documentation can be found at http://pillow.readthedocs.org/en/latest/reference.
然后,您显然需要控制两个图像的纵横比在整个程序中的变化方式。例如,thumbnail()
不会 改变图像的纵横比,即使您的 size
元组与原始图像的纵横比不同。引自 thumbnail()
文档:
This method modifies the image to contain a thumbnail version of
itself, no larger than the given size. This method calculates an
appropriate thumbnail size to preserve the aspect of the image
所以,我不确定您使用 (643,597)
元组的确切位置,以及您之后是否可能依赖缩略图来获得这个确切的大小。
我一直在尝试叠加 python 中的两个图像以匹配坐标,左上角和右下角具有相同的坐标,并且它们的外观几乎相同,只有几个像素。虽然是不同的分辨率。
使用PIL我已经能够叠加图像,虽然在叠加它们之后图像输出是正方形但分辨率是背景图像的分辨率,前景图像也被错误地重新调整大小(据我所知看)。我一定是做错了什么。
import Image
from PIL import Image
#load images
background = Image.open('ndvi.png')
foreground = Image.open('out.png')
#resizing
foreground.thumbnail((643,597),Image.ANTIALIAS)
#overlay
background.paste(foreground, (0, 0), foreground)
#save
background.save("overlay.png")
#display
background.show()
当将图像放入像 powerpoint 这样可怕的东西时,图像方面几乎完全相同。我已经包含了一个示例图像,左边的图像是我的手动叠加层,右边的图像是 python 的输出。代码中某些点的背景被垂直挤压,也影响了覆盖。我希望能够在 python 中执行此操作并使它看起来像左手图像一样正确。
前期解决方案。
背景图片
width/height/ratio: 300 / 375 / 0.800
前景图片
width/height/ratio: 400 / 464 / 0.862
叠加
from PIL import Image
imbg = Image.open("bg.png")
imfg = Image.open("fg.png")
imbg_width, imbg_height = imbg.size
imfg_resized = imfg.resize((imbg_width, imbg_height), Image.LANCZOS)
imbg.paste(imfg_resized, None, imfg_resized)
imbg.save("overlay.png")
讨论
您在问题中提供的最重要的信息是:
- 前景和背景图片的纵横比不相等,但相似
- 两张图片的左上角和右下角最后需要对齐。
从这些点得出的结论是:其中一张图片的纵横比必须改变。这可以通过 resize()
方法实现(而不是 thumbnail()
,如下所述)。总而言之,目标就是:
将尺寸较大的图像(前景图像)调整为较小背景图像的精确尺寸。即不一定保持前景图片的纵横比。
这就是上面的代码所做的。
对您的方法的两条评论:
首先,我推荐使用最新版本的Pillow(Pillow是PIL的延续项目,它是API兼容的)。在 2.7 版本中 they have largely improved the image re-scaling quality. The documentation can be found at http://pillow.readthedocs.org/en/latest/reference.
然后,您显然需要控制两个图像的纵横比在整个程序中的变化方式。例如,thumbnail()
不会 改变图像的纵横比,即使您的 size
元组与原始图像的纵横比不同。引自 thumbnail()
文档:
This method modifies the image to contain a thumbnail version of itself, no larger than the given size. This method calculates an appropriate thumbnail size to preserve the aspect of the image
所以,我不确定您使用 (643,597)
元组的确切位置,以及您之后是否可能依赖缩略图来获得这个确切的大小。