【问题标题】:Break long drawn text to multiple lines with Pillow使用 Pillow 将绘制的长文本分成多行
【发布时间】:2019-09-21 14:46:01
【问题描述】:

我正在创建一个在 128x48 小图像上绘制文本的小型 Python 程序。 它适用于仅达到 120 宽度的文本,但我不知道如何将较长的文本拆分为另一行。我该怎么做?

我尝试使用 textwrap3,但无法让它与 Pillow 一起使用。

该程序创建 128x48 的图像文件,带有黑色背景和黄色居中的文本,稍后应该在输出高达 480i 的设备上查看,因此只需将文本 大大 缩小以适应额外的文本宽度不会有帮助。当前使用的字体是 Arial 18。

这是用于创建图像的当前代码:

from PIL import Image, ImageDraw, ImageFont

AppName = "TextGoesHere"
Font = ImageFont.truetype('./assets/Arial.ttf', 18)
img = Image.new('RGB', (128, 48), color='black')
d = ImageDraw.Draw(img)

# Get width and height of text
w, h = d.textsize(AppName, font=Font)

# Draw text
d.text(((128-w)/2, (48-h)/2), AppName, font=Font, fill=(255, 255, 0))

img.save('icon.png')

以上代码输出图像如下:

宽度大于图像的较长文本输出如下(LongerTextGoesHere):

想要的结果应该与此类似:

【问题讨论】:

  • 你的单词之间真的没有空格吗?怎么会有人知道在哪里明智地拆分它们?您是否考虑过改变字体的大小以及分布在多行上?

标签: python python-imaging-library


【解决方案1】:

这里有一些代码使用 PIL/Pillow 的二进制搜索将文本分成合适的部分。

def break_fix(text, width, font, draw):
    if not text:
        return
    lo = 0
    hi = len(text)
    while lo < hi:
        mid = (lo + hi + 1) // 2
        t = text[:mid]
        w, h = draw.textsize(t, font=font)
        if w <= width:
            lo = mid
        else:
            hi = mid - 1
    t = text[:lo]
    w, h = draw.textsize(t, font=font)
    yield t, w, h
    yield from break_fix(text[lo:], width, font, draw)

def fit_text(img, text, color, font):
    width = img.size[0] - 2
    draw = ImageDraw.Draw(img)
    pieces = list(break_fix(text, width, font, draw))
    height = sum(p[2] for p in pieces)
    if height > img.size[1]:
        raise ValueError("text doesn't fit")
    y = (img.size[1] - height) // 2
    for t, w, h in pieces:
        x = (img.size[0] - w) // 2
        draw.text((x, y), t, font=font, fill=color)
        y += h

img = Image.new('RGB', (128, 48), color='black')
fit_text(img, 'LongerTextGoesHere', (255,255,0), Font)
img.show()

【讨论】:

  • 对此我有一个小问题,如果我希望将这些文本块切割成不同的行,同时“最好”在有空格的情况下切割,这样可以保留其含义
  • @FrenchNoodles 我按要求回答了这个问题。如果您有其他问题,请提出 - 如果需要,您可以参考这个问题。
【解决方案2】:

如果您使用 ImageMagick,您可以非常简单地做到这一点,而无需编写任何 Python,它安装在大多数 Linux 发行版上并且可用于 macOS 和 Windows。所以,就在终端:

convert -size 128x48 -background black -font Arial -fill yellow -gravity center caption:"Some Text" result.png

或者,使用更长的文本字符串:

convert -size 128x48 -background black -font Arial -fill yellow -gravity center caption:"Some Really Really Long Text" result.png

如果您真的非常想编写 Python,WandImageMagick 的 Python 绑定,函数名称将反映上面使用的名称。

【讨论】:

  • 我更喜欢使用 PIL 或 Pillow,以避免需要外部依赖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多