Nei*_*eil 14 python python-imaging-library
我正在使用PIL在图像上绘制文字.我如何包装一串文字.这是我的代码:
text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
image = Image.open("/tmp/background-image.jpg")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"), 50, encoding='unic')
draw.text((100, 100), text, font=font, fill="#aa0000")
image.save("/tmp/image.jpg")
Run Code Online (Sandbox Code Playgroud)
ekh*_*oro 14
您需要先将文本拆分为正确长度的行,然后单独绘制每一行.
第二部分很简单,但如果使用可变宽度字体,第一部分可能非常棘手.如果使用固定宽度字体,或者精度无关紧要,那么您可以使用textwrap模块将文本拆分为给定字符宽度的行:
margin = offset = 40
for line in textwrap.wrap(text, width=40):
draw.text((margin, offset), line, font=font, fill="#aa0000")
offset += font.getsize(line)[1]
Run Code Online (Sandbox Code Playgroud)
追求简单一致的行为。正如其他答案中所述,该textwrap模块仅正确处理固定宽度字体(因此这不是一个一致的解决方案)。这是一个简单的函数,可以在不破坏单词的情况下换行文本,并且它适用于可变宽度字体。
from PIL import ImageFont
def get_wrapped_text(text: str, font: ImageFont.ImageFont,
line_length: int):
lines = ['']
for word in text.split():
line = f'{lines[-1]} {word}'.strip()
if font.getlength(line) <= line_length:
lines[-1] = line
else:
lines.append(word)
return '\n'.join(lines)
if __name__ == '__main__':
font = ImageFont.truetype('arial.ttf', 12)
text = 'An example line of text that will need to be wrapped.'
wrapped_text = get_wrapped_text(text, font, line_length=70)
# wrapped_text is 'An example\nline of text\nthat will\nneed to be\nwrapped.'
Run Code Online (Sandbox Code Playgroud)
好了,当然,您可以在每次要换行时使用\ n手动进行此操作。如果每次都使用不同的字符串,但这不是最好的方法,而是完全控制结果。但是也有textwrap模块。您可以通过以下方式使用它:
import textwrap
texto = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
novo = textwrap.wrap(texto, width=20)
print(novo)
Run Code Online (Sandbox Code Playgroud)
结果:
>>>
['Lorem ipsum dolor', 'sit amet,', 'consectetur', 'adipisicing elit,', 'sed do eiusmod', 'tempor incididunt ut', 'labore et dolore', 'magna aliqua. Ut', 'enim ad minim', 'veniam, quis nostrud', 'exercitation ullamco', 'laboris nisi ut', 'aliquip ex ea', 'commodo consequat.', 'Duis aute irure', 'dolor in', 'reprehenderit in', 'voluptate velit esse', 'cillum dolore eu', 'fugiat nulla', 'pariatur. Excepteur', 'sint occaecat', 'cupidatat non', 'proident, sunt in', 'culpa qui officia', 'deserunt mollit anim', 'id est laborum.']
Run Code Online (Sandbox Code Playgroud)
返回根据您确定的宽度包装的上一个字符串的术语列表。
接受的解决方案基于每行 40 个字符的固定限制来换行文本,不考虑框宽度(以像素为单位)或字体大小。这很容易导致填充不足或溢出。
这是一个更好的解决方案 - 一个简单的代码片段,用于考虑基于字体的宽度测量来包装文本:https : //gist.github.com/turicas/1455973
| 归档时间: |
|
| 查看次数: |
8282 次 |
| 最近记录: |