如何使用循环重复随机组合图像并正确插入 A4 格式?

How to repeat the random combination of images using loop and insert them in A4 format correctly?

我正在尝试让这个简短的脚本工作,它随机覆盖 3 个不同的图像(请参见下面的图像 link)。它必须循环 N 次,然后 assemble 它们最后变成一张(可能)A4 大小的图像。我已经尝试过几次不同的组合,但我很困惑,无法让循环正常工作(图像都是第一个的相同副本,并在右侧继续粘贴)都不适合 A4 格式的图像。非常感谢任何帮助!

背景:

橙色圆点:

白X(透明背景):

错误结果:

所需的输出(请注意,橙色点实际上每次都打印在不同的位置,但我无法正确创建输出):

https://ibb.co/n1XNz9K

注意:我删除了 A4 代码片段,因为它只是弄乱了脚本。

from PIL import Image
import random

#bckgnd = 200x200
#whiteX = 200x200
#orangedot = 30x30

bckgnd = Image.open('background2.png').convert('RGBA')  # Convert to mode supporting alpha.

orangedot = Image.open('orangedot.png')
orangedot_x, orangedot_y = random.randint(30, 170), random.randint(0, 100)
tmp_img = Image.new('RGBA', bckgnd.size, color=(0, 0, 0, 0))
tmp_img.paste(orangedot, (orangedot_x, orangedot_y))
bckgnd.alpha_composite(tmp_img)

whiteX = Image.open('whiteX.png')
tmp_img = Image.new('RGBA', bckgnd.size, color=(0, 0, 0, 0))
tmp_img.paste(whiteX)  # Assumes it's the same size as background image.
bckgnd.alpha_composite(tmp_img)



bckgnd.save("test.png")
bckgnd.show()


img_to_paste = Image.open('test.png')
width, height = img_to_paste.size

n = 20  # paste image n-times

img = Image.new('RGBA', (width * n, height), color=(0, 0, 0, 0))  # set width, height of new image
img.save('out.png')

for i in range(0, n):
    out = Image.open('out.png')
    out.paste(img_to_paste, (i * width, 0))  # the second argument here is tuple representing upper left corner
    out.save('out.png')

#img.show()

像A4纸大小的图片,只要选择像dpi = 300这样的分辨率,然后根据实际A4纸大小计算xy方向需要的tile数21.0 cm x 29.7 cm 和分辨率。限制为整个图块,即您的最终图像将变得比实际 A4 小一点。

既然你现在已经有了 xy 方向的图块数量,只需设置一个嵌套的 for 循环,并直接访问最终图像中的每个图块。在那里,粘贴背景图像、随机生成位置的橙色圆点图像,最后粘贴白色 X 图像。

这就是我的解决方案:

from math import floor
from PIL import Image
from random import randint

# Read all images
bckgnd = Image.open('background2.png').convert('RGBA')
orangedot = Image.open('orangedot.png')
whiteX = Image.open('whiteX.png')

# Width and height of each "tile"
w, h = bckgnd.size

# Calculate number of tiles for x and y direction by A4 paper size
# (21 cm x 29.7 cm), and some resolution like dpi = 300
n_tiles = (floor((21.0 / 2.54 * 300) / w), floor((29.7 / 2.54 * 300) / h))

# Prepare final image of sufficient size
final_img = Image.new('RGBA', (n_tiles[0] * w, n_tiles[1] * h), color=(0, 0, 0, 0))

# Iterate all tiles
for i_x in range(n_tiles[0]):
    for i_y in range(n_tiles[1]):

        # Upper left (x, y) coordinates of current tile
        x, y = i_x * w, i_y * h

        # 1st: Paste background to current tile
        final_img.paste(bckgnd, (x, y), mask=bckgnd)

        # 2nd: Randomly generate location of orange dot and paste to current tile
        od_x, od_y = randint(30, 170), randint(0, 100)
        final_img.paste(orangedot, (x + od_x, y + od_y), mask=orangedot)

        # 3rd: Paste white X to current tile
        final_img.paste(whiteX, (x, y), mask=whiteX)

# Save and show final image
final_img.save('final_img.png')
final_img.show()

然后,这就是输出:

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1.1
Pillow:        8.2.0
----------------------------------------