如何解决PIL中ImageDraw绘制文本超出期望长度的问题
解决方案
Pillow的ImageDraw.text()没有内置自动换行参数,你可以通过调用文本宽度测量方法实现自动换行,实现逻辑简单,不需要手动统计字符数量:
实现思路
- 预设文本最大展示宽度(可根据你的画布需求自定义,比如设置为图片宽度减左右边距)
- 将文本按空格拆分为单词(如果是中文可以直接拆分为单个字符)
- 逐词拼接当前行,每次拼接前计算拼接后文本的总宽度,超过最大宽度则换行存储当前行,从下一行开始拼接当前单词
- 逐行绘制文本,每行的Y坐标按行高递进,行高可通过字体属性直接获取
可直接运行的修改后代码
from PIL import Image, ImageDraw, ImageFont # 导入图片 picture = Image.open("examplefile.png") d1 = ImageDraw.Draw(picture) myFont = ImageFont.truetype('./Roboto/Roboto-Medium.ttf', 50) text = "Lorem ipsum dolor sit amet quod voluptas illum illo quas at inventore eos nostrum. Voluptatem commodi dignissimos sed consequatur. Rerum qui numquam nobis quo distinctio." # 自定义配置:文本最大宽度、起始绘制坐标、行间距系数 max_width = 800 # 这里改成你需要的预设宽度 start_x = 0 start_y = 0 line_spacing = 1.2 # 行高为字体大小乘以该系数,可调整 # 自动换行处理 lines = [] current_line = "" for word in text.split(): # 测试拼接当前单词后的宽度 test_line = current_line + word + " " test_width = d1.textlength(test_line, font=myFont) if test_width <= max_width: current_line = test_line else: lines.append(current_line) current_line = word + " " # 加入最后一行 lines.append(current_line) # 逐行绘制文本 y_offset = start_y font_height = myFont.getmetrics()[0] for line in lines: d1.text((start_x, y_offset), line, fill=(0, 0, 0), font=myFont) y_offset += font_height * line_spacing # 保存测试 picture.save("output.png")
补充说明
如果需要处理中英混合文本,只需要调整拆分逻辑,中文部分按单字符拆分、英文按单词拆分即可,测量宽度的逻辑通用。
内容的提问来源于stack exchange,提问作者EncryptEx
相关产品推荐
相关产品推荐

