我正在使用 Wand 生成一个 JPG,其中包含自定义变量文本。 我有一个宽度相同但高度不同的字符串数组。 是否有一种方法可以在边界内自动换行长文本或计算文本所需的高度,以便从数组中绘制文本时它们不会重叠。
with Drawing() as ctx:
with Image(width=1080, height=1080, background=Color("WHITE")) as img:
with Drawing() as draw:
for i,line in enumerate(lines):
metrics = draw.get_font_metrics(img, line, multiline=True)
draw.text(x=150, y=120+(i*35)+int(metrics.text_height), body=line)
draw(img)
img.sample(1080, 1080)
img.save(filename="output.png")
最佳答案
这可能不是您正在寻找的答案,但希望能让您走上正确的道路。
How do I measure the bounds of a string in wand?
你已经这么做了。我建议采用一种更经典的偏移和累加器方法来映射每次迭代更新的位置,而不是“智能快速”的单行方法。
top_margin = 120
line_offset = 0
line_padding = 35
with Drawing() as ctx:
with Image(width=1080, height=1080, background=Color("WHITE")) as img:
with Drawing() as draw:
for i,line in enumerate(lines):
metrics = draw.get_font_metrics(img, line, multiline=True)
draw.text(x=150, y=y=top_margin + line_offset, body=line)
line_offset += int(metrics.text_height) + line_padding
Is there a method to word wrap a long text inside a boundary or calculate the height needed for the text so when drawing the texts from the array they don't overlap.
简短的回答是否。您将负责实现该算法。幸运的是,互联网上充满了可供引用的示例和研究文章。它可以像查找溢出前的最后一个空间一样基本......
lines = [
'I\'m using Wand to generate a JPG with custom variable text inside it.',
'I have an array of strings all with the same width but different heights',
'Is there a method to word wrap a long text inside a boundary or calculate the height needed for the text so when drawing the texts from the array they don\'t overlap',
]
image_width = 540
image_height = 540
left_margin = 150
right_margin = image_width - left_margin * 2
top_margin = 120
line_padding = 35
line_offset = 0
with Drawing() as ctx:
with Image(width=image_width, height=image_height, background=Color("LIGHTCYAN")) as img:
with Drawing() as draw:
for i,line in enumerate(lines):
metrics = draw.get_font_metrics(img, line, multiline=True)
last_idx = 1
# Do we need to do work?
while metrics.text_width > right_margin:
last_breakpoint=0
# Scan text for possible breakpoints.
for idx in range(last_idx, len(line)):
if line[idx] == ' ':
last_breakpoint = idx
else:
# Determine if we need to insert a breakpoint.
metrics = draw.get_font_metrics(img, line[:idx], multiline=True)
if metrics.text_width >= right_margin:
line = line[:last_breakpoint].strip() + '\n' + line[last_breakpoint:].strip()
last_idx = last_breakpoint
break
# Double check any modifications to text was successful enough.
metrics = draw.get_font_metrics(img, line, multiline=True)
draw.text(x=left_margin, y=top_margin + line_offset, body=line)
line_offset += int(metrics.text_height) + line_padding
draw(img)
img.save(filename="output.png")
上面的代码可以优化,Python 可能已经包含了一些 better methods .
进一步阅读...
source code ImageMagick 的 CAPTION:
协议(protocol)就是一个很好的例子。该算法重复调用 GetMultilineTypeMetrics
以及 FormatMagickCaption
调整点大小并插入换行符。
wand 库并不真正支持字幕协议(protocol),但您可以使用以下解决方法来使用它。
from wand.api import library
# ...
with Image(width=image_width, height=image_height, background=Color("LIGHTCYAN")) as img:
for i,line in enumerate(lines):
# Create a tempory image for each bounding box
with Image() as throwaway:
library.MagickSetSize(throwaway.wand, right_margin, line_padding)
throwaway.read(filename='CAPTION:'+line)
img.composite(throwaway, left_margin, top_margin + line_offset)
line_offset += line_padding + throwaway.height
img.save(filename="output.png")
关于python - 如何测量魔杖中绳子的边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52611641/