如何使用循环重复随机组合图像并正确插入 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(透明背景):
错误结果:
所需的输出(请注意,橙色点实际上每次都打印在不同的位置,但我无法正确创建输出):
注意:我删除了 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纸大小计算x
和y
方向需要的tile数21.0 cm x 29.7 cm
和分辨率。限制为整个图块,即您的最终图像将变得比实际 A4 小一点。
既然你现在已经有了 x
和 y
方向的图块数量,只需设置一个嵌套的 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
----------------------------------------
我正在尝试让这个简短的脚本工作,它随机覆盖 3 个不同的图像(请参见下面的图像 link)。它必须循环 N 次,然后 assemble 它们最后变成一张(可能)A4 大小的图像。我已经尝试过几次不同的组合,但我很困惑,无法让循环正常工作(图像都是第一个的相同副本,并在右侧继续粘贴)都不适合 A4 格式的图像。非常感谢任何帮助!
背景:
橙色圆点:
白X(透明背景):
错误结果:
所需的输出(请注意,橙色点实际上每次都打印在不同的位置,但我无法正确创建输出):
注意:我删除了 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纸大小计算x
和y
方向需要的tile数21.0 cm x 29.7 cm
和分辨率。限制为整个图块,即您的最终图像将变得比实际 A4 小一点。
既然你现在已经有了 x
和 y
方向的图块数量,只需设置一个嵌套的 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
----------------------------------------