【问题标题】:How do I paste multiple images onto one image and output multiple other images?如何将多张图片粘贴到一张图片上并输出多张其他图片?
【发布时间】:2021-08-16 15:38:56
【问题描述】:

我正忙着写一些东西来操作图像并将其他图像粘贴到它上面。

我正在尝试将背景和狗的帽子更改为各种其他的,并输出带有随机生成图像的多个文件。输入图像来自文件夹(backgroundshats)。当我们拍照并将它们复制到名为 background 的文件夹中时,我希望能够通过从 backgrounds 文件夹中选择一个随机图像来运行我的 Python 脚本来更改狗的背景。我希望能够对hats 文件夹中的图像执行相同的操作。随着时间的推移会添加更多文件夹,但这是另一天的问题。

到目前为止,我可以将项目粘贴到主图像上。我在文件夹中有多个 PNG 文件,我得到了三个图像,但所有三个图像都是相同的。我的代码似乎只加载了一个背景和一顶帽子。

请帮助我将两个文件夹中的随机图像粘贴到我的狗的主图像上。狗保持静止,但背景和帽子会改变。选项应该与组合允许的一样多。因此,三个具有三个选项的文件夹将有很多组合选项。我已将限制设置为三个,但每次图像应呈现不同的组合。

到目前为止我的代码:

import glob
from PIL import Image

def main():

    q = 0
    hat_image = glob.glob("hats/*.png")
    for image in hat_image:
        with open(image, 'rb') as file:
            hat = Image.open(file)

    bg_image = glob.glob("backgrounds/*.png")
    for image in bg_image:
        with open(image, 'rb') as file:
            bg = Image.open(file)

    try:
        while q < 3:
            img = Image.open("base.png")
            img.paste(hat, (276, 176), hat)
            # mouth = Image.open("./mouth/mouth1.png")
            img.paste(bg, (226,476), bg)
            img.save("final{}.png".format(q), "PNG")
            q += 1

    except IOError:
        pass

if __name__ == "__main__":
    main()

【问题讨论】:

  • 请提供真正最小的minimal reproducible example
  • stackoverflow.com/questions/306400/… 如何从列表中随机选择一个项目? : 示例添加导入随机,删除 for 循环,使用 open(random.choice(hat_image), 'rb') 作为文件:使用 open(random.choice(bg_image), 'rb') 作为文件
  • 我会尝试提供一个真正最小的例子。

标签: python image python-imaging-library


【解决方案1】:

如果您想要背景和帽子图像的所有可能组合,您只需进行相应的迭代,即使用嵌套的for 循环:

import glob

from PIL import Image

bg_filenames = glob.glob('backgrounds/*.png')
hat_filenames = glob.glob('hats/*.png')
dog_image = Image.open('dog.png')

for bg_filename in bg_filenames:
    for hat_filename in hat_filenames:
        output_image = Image.open(bg_filename)
        output_image.paste(dog_image)
        output_image.paste(Image.open(hat_filename))
        output_image.save('output/{}_{}.png'.format(
            bg_filename.split('\\')[1].split('.png')[0],
            hat_filename.split('\\')[1].split('.png')[0]
        ))

print(glob.glob('output/*.png'))
# ['output\\alley_baseball.png',
#  'output\\alley_cowboy.png',
#  'output\\alley_fedora.png',
#  'output\\garden_baseball.png',
#  'output\\garden_cowboy.png',
#  'output\\garden_fedora.png',
#  'output\\park_baseball.png',
#  'output\\park_cowboy.png',
#  'output\\park_fedora.png']

如果您确实希望每次执行时使用随机选择的背景和帽子的单个图像,只需使用randint w.r.t。背景和帽子图像的数量:

import glob

from PIL import Image
from random import randint

bg_filenames = glob.glob('backgrounds/*.png')
hat_filenames = glob.glob('hats/*.png')
dog_image = Image.open('dog.png')

bg_filename = bg_filenames[randint(0, len(bg_filenames)-1)]
hat_filename = hat_filenames[randint(0, len(hat_filenames)-1)]

output_image = Image.open(bg_filename)
output_image.paste(dog_image)
output_image.paste(Image.open(hat_filename))
output_image.save('output/{}_{}.png'.format(
    bg_filename.split('\\')[1].split('.png')[0],
    hat_filename.split('\\')[1].split('.png')[0]
))

print(glob.glob('output/*.png'))
# ['output\\alley_cowboy.png',
#  'output\\garden_baseball.png',
#  'output\\garden_fedora.png']                 After three runs

对于这两个版本,您都可以轻松添加更多文件夹,例如 shoesgloves 或其他。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19042-SP0
Python:        3.9.6
PyCharm:       2021.2
Pillow:        8.3.1
----------------------------------------

【讨论】:

  • 谢谢,这很有道理。如果我要限制输出文件的数量,我会使用 while 循环吗? IE。我不希望它运行并创建 1000 张图片。我试过你的例子,但得到错误。 ``` Traceback(最近一次调用最后):文件“example.py”,第 17 行,在 bg_filename.split('\\')[1].split('.png')[0],IndexError : list index out of range ``` 我还没来得及调试呢。稍后将对此进行调查。
猜你喜欢
  • 2015-10-09
  • 1970-01-01
  • 2020-05-06
  • 2013-02-24
  • 1970-01-01
  • 2016-09-07
  • 2017-03-21
  • 2016-03-31
相关资源
最近更新 更多