在图像上重复创建文本的算法
Algorithm to create text on image repeatedly
使用 Python 和 PIL,我打算在现有图像上绘制文本。
我有一个图像,上面有 12 个部分,我有一个数组,如下所示:
array = [
[1,'ABC'],
[2,'DEF'],
[3,'XYZ'],
[4,'aa1'],
[1,'pqr'],
[7,'etc'],
[3,'klm'],
[9,'bb'],
[2,'aa'],
[10,'xyz'],
[11,'abc'],
[1,'def'],
]
现在,根据 a[0] for a in array
中的数字,我必须将 a[1]
的文本放在图像的 1-12
部分中。我试过这个:
for a in arr_vals:
if a[0] == 1:
draw.text((337, 140), a[1], (231, 76, 60), font=font)
elif a[0] == 2:
draw.text((149, 62), a[1], (231, 76, 60), font=font)
elif a[0] == 3:
draw.text((337, 156), a[1], (231, 76, 60), font=font)
现在很明显,出现的问题是,在上面的示例中,array[0]
和 array[4]
在第一个索引中具有相同的值。这将导致图像中的文本被覆盖。在这种情况下如何防止覆盖?将文本递归地放置在图像上的理想算法是什么?
编辑:
我想要的:红色文本应该出现在 12 个部分的任何一个中,具体取决于数组。
当前生成的图像:
如您所见,由于代码中的相同位置,生成的图像具有重叠的文本。
您可以将您的项目组织成一个集合,按相似的区域编号将它们分组。然后对于每个区域,您可以使用递增的 y 坐标渲染第一行之后的每一行文本,因此后面的行显示在前面的行下方,而不是直接在它们之上。示例:
array = [
[1,'ABC'],
[2,'DEF'],
[3,'XYZ'],
[4,'aa1'],
[1,'pqr'],
[7,'etc'],
[3,'klm'],
[9,'bb'],
[2,'aa'],
[10,'xyz'],
[11,'abc'],
[1,'def'],
]
d = {}
for item in array:
d.setdefault(item[0], []).append(item[1])
print d
#d now contains something that looks like:
#{1: ['ABC', 'pqr', 'def'], 2: ['DEF', 'aa'], 3:...}
#height of a single line of text, in pixels.
#I don't know what this should actually be. Depends on your font size, I guess.
line_height = 20
color = (231, 76, 60)
for area in d.iterkeys():
#somehow get the base coordinates for this particular area.
#you originally used a lot of if-elifs, but a dict could work too.
coords = ???
y_offset = 0
for line in d[area]:
draw.text(coords[0], coords[1]+y_offset, line, color, font=font)
y_offset += line_height
使用 Python 和 PIL,我打算在现有图像上绘制文本。
我有一个图像,上面有 12 个部分,我有一个数组,如下所示:
array = [
[1,'ABC'],
[2,'DEF'],
[3,'XYZ'],
[4,'aa1'],
[1,'pqr'],
[7,'etc'],
[3,'klm'],
[9,'bb'],
[2,'aa'],
[10,'xyz'],
[11,'abc'],
[1,'def'],
]
现在,根据 a[0] for a in array
中的数字,我必须将 a[1]
的文本放在图像的 1-12
部分中。我试过这个:
for a in arr_vals:
if a[0] == 1:
draw.text((337, 140), a[1], (231, 76, 60), font=font)
elif a[0] == 2:
draw.text((149, 62), a[1], (231, 76, 60), font=font)
elif a[0] == 3:
draw.text((337, 156), a[1], (231, 76, 60), font=font)
现在很明显,出现的问题是,在上面的示例中,array[0]
和 array[4]
在第一个索引中具有相同的值。这将导致图像中的文本被覆盖。在这种情况下如何防止覆盖?将文本递归地放置在图像上的理想算法是什么?
编辑:
我想要的:红色文本应该出现在 12 个部分的任何一个中,具体取决于数组。
当前生成的图像:
如您所见,由于代码中的相同位置,生成的图像具有重叠的文本。
您可以将您的项目组织成一个集合,按相似的区域编号将它们分组。然后对于每个区域,您可以使用递增的 y 坐标渲染第一行之后的每一行文本,因此后面的行显示在前面的行下方,而不是直接在它们之上。示例:
array = [
[1,'ABC'],
[2,'DEF'],
[3,'XYZ'],
[4,'aa1'],
[1,'pqr'],
[7,'etc'],
[3,'klm'],
[9,'bb'],
[2,'aa'],
[10,'xyz'],
[11,'abc'],
[1,'def'],
]
d = {}
for item in array:
d.setdefault(item[0], []).append(item[1])
print d
#d now contains something that looks like:
#{1: ['ABC', 'pqr', 'def'], 2: ['DEF', 'aa'], 3:...}
#height of a single line of text, in pixels.
#I don't know what this should actually be. Depends on your font size, I guess.
line_height = 20
color = (231, 76, 60)
for area in d.iterkeys():
#somehow get the base coordinates for this particular area.
#you originally used a lot of if-elifs, but a dict could work too.
coords = ???
y_offset = 0
for line in d[area]:
draw.text(coords[0], coords[1]+y_offset, line, color, font=font)
y_offset += line_height