有一些图片,每张图片有对应的文本,需要一张一张拼接为 N 行 M 列的形式,每张图片的文本显示在它下方,文字没有换行,太多的话会很叠在一起
from PIL import Image, ImageDraw, ImageFont
# 获取图片和对应文本的列表
images_and_texts = [
('img/1.png', '阿萨法大使'),
('img/2.png', 'I两个花见花开就还好归纳刚发'),
('img/3.png', '发给还能给你发的那个让他很尬虽然'),
('img/4.png', '阿啊省公司辅导班v没搞错没法干画法高浩然回来后'),
('img/5.png', '发生的你付款就是你的科技归纳科技南国际卡'),
('img/6.png', 'v出门询价单你发几个黄大发'),
('img/7.png', '想你MV帮忙下班v计划'),
('img/8.png', '破会有你,你,没看到两三年饭卡好地方'),
('img/9.png', '阿妈审批单看懂iUR哦是吗佛困哪扫地机个'),
('img/10.png', '说法你啊滚你爸吃米线,i1'),
('img/11.png', '阿萨法聚会那你可能尽快回iu'),
('img/12.png', '实惠哦接哦i价格哦in了看那看归纳,,'),
]
# 设置字体和字体大小
font_path = "simhei.ttf" # 请替换为你系统中存在的字体文件路径
font_size = 50
# 获取最大图片尺寸
max_width = 0
max_height = 0
for img_file, _ in images_and_texts:
with Image.open(img_file) as img:
max_width = max(max_width, img.width)
max_height = max(max_height, img.height)
# 调整网格布局以适应12张图片
grid_rows = 3
grid_cols = 4
# 创建新图像
new_img = Image.new('RGB', (max_width * grid_cols, max_height * grid_rows), (255, 255, 255))
# 定义字体对象
font = ImageFont.truetype(font_path, font_size)
# 在新图像上放置图片和文本
index = 0
for row in range(grid_rows):
for col in range(grid_cols):
if index < len(images_and_texts):
img_file, text = images_and_texts[index]
with Image.open(img_file) as img:
img_resized = img.resize((max_width, max_height), Image.ANTIALIAS)
new_img.paste(img_resized, (max_width * col, max_height * row))
draw = ImageDraw.Draw(new_img)
text_width, text_height = draw.textsize(text, font=font)
text_pos = ((max_width - text_width) // 2 + max_width * col, max_height * (row + 1) - text_height)
draw.text(text_pos, text, fill=(255, 0, 0), font=font)
index += 1
# 保存最终图像
new_img.save("merged_image.jpg")
如果只想拼接图片,把这几行注释掉就可以
# draw = ImageDraw.Draw(new_img)
# text_width, text_height = draw.textsize(text, font=font)
# text_pos = ((max_width - text_width) // 2 + max_width * col, max_height * (row + 1) - text_height)
# draw.text(text_pos, text, fill=(255, 0, 0), font=font)
如果想把文字显示在上方,并且按照每 15 个字换一行:
from PIL import Image, ImageDraw, ImageFont
images_and_texts = [
('img/1.png', '阿萨法大使'),
('img/2.png', 'I两个花见花开就还好归纳刚发'),
('img/3.png', '发给还能给你发的那个让他很尬虽然'),
('img/4.png', '阿啊省公司辅导班v没搞错没法干画法高浩然回来后'),
('img/5.png', '发生的你付款就是你的科技归纳科技南国际卡'),
('img/6.png', 'v出门询价单你发几个黄大发'),
('img/7.png', '想你MV帮忙下班v计划'),
('img/8.png', '破会有你,你,没看到两三年饭卡好地方'),
('img/9.png', '阿妈审批单看懂iUR哦是吗佛困哪扫地机个'),
('img/10.png', '说法你啊滚你爸吃米线,i1'),
('img/11.png', '阿萨法聚会那你可能尽快回iu'),
('img/12.png', '实惠哦接哦i价格哦in了看那看归纳,,'),
]
def stitch_images_together(images_and_texts, output_filename, rows, cols):
"""
# 获取图片和对应文本的列表
images_and_texts = [
('img/1.png', '阿萨法大使'),
('img/2.png', 'I两个花见花开就还好归纳刚发'),
...
]
"""
# 设置字体和字体大小
font_path = "simhei.ttf" # 请替换为你系统中存在的字体文件路径
font_size = 30
# 获取最大图片尺寸
max_width = 0
max_height = 0
for img_file, _ in images_and_texts:
with Image.open(img_file) as img:
max_width = max(max_width, img.width)
max_height = max(max_height, img.height)
# 创建新图像
new_img = Image.new('RGB', (max_width * cols, max_height * rows), (255, 255, 255))
# 定义字体对象
font = ImageFont.truetype(font_path, font_size)
# 在新图像上放置图片和文本
index = 0
for row in range(rows):
for col in range(cols):
if index < len(images_and_texts):
img_file, text = images_and_texts[index]
with Image.open(img_file) as img:
img_resized = img.resize((max_width, max_height), Image.ANTIALIAS)
new_img.paste(img_resized, (max_width * col, max_height * row))
# 文本换行处理
# 将文本分割为每15个字符一行
max_chars_per_line = 15
wrapped_text = ''
for i in range(0, len(text), max_chars_per_line):
wrapped_text += text[i:i + max_chars_per_line] + '\n'
text_lines = wrapped_text.split('\n') # 将换行文本分割成多行
# 绘制文本到新图像上,从图片顶部开始
draw = ImageDraw.Draw(new_img)
y_offset = max_height * row # 文本起始Y坐标设为当前图片的顶部
for line_index, line in enumerate(text_lines):
# 计算换行文本每一行的实际高度
line_width, line_height = draw.textsize(line, font=font)
x_offset = (max_width - line_width) // 2 + max_width * col # 文本居中X坐标不变
y_line_pos = y_offset + line_height * line_index # 每一行Y坐标递增
draw.text((x_offset, y_line_pos), line, fill=(255, 0, 0), font=font)
index += 1
# 保存最终图像
new_img.save(output_filename)
stitch_images_together(images_and_texts, 'test.jpg', 3, 4)