簡體   English   中英

從給定文本生成圖像

[英]Generate image from given text

我有一個函數,它使用 Pillow 生成給定文本的圖像表示,使用作為輸入textfontfont_sizecolor 該函數通過生成一個空的 RGBA 圖像開始工作,然后在其上繪制文本,最后裁剪結果以僅保留文本。

現在,在 99% 的情況下,該功能運行良好,但對於更大的字體,我需要更大的畫布開始,否則文本會被剪裁。 出於這個原因,我將初始畫布設置為具有非常高的值,例如(10k, 10k)像素。 這個初始圖像大小減慢了整個過程,我想知道是否有辦法獲得相同的結果而不必求助於初始的空圖像,或者生成的初始圖像大小盡可能小為了不

我的功能是這樣的:

def text_to_image(
    text: str,
    font_filepath: str,
    font_size: int,
    color: Tuple[int, int, int, int],
) -> ImageType:
    # ?: very big canvas size as to not to clip the text when rendered with bigger font sizes
    canvas_size = (
        10000,
        10000,
    )
    img = Image.new("RGBA", canvas_size)

    draw = ImageDraw.Draw(img)
    draw_point = (0, 0)

    font = ImageFont.truetype(font_filepath, size=font_size)
    draw.multiline_text(draw_point, text, font=font, fill=color)

    text_window = img.getbbox()
    img = img.crop(text_window)

    return img

樣本結果:

在此處輸入圖像描述


編輯:

感謝@AKX 的超快速響應解決了我的問題。 對於任何感興趣的人,該功能變為

def text_to_image(
    text: str,
    font_filepath: str,
    font_size: int,
    color: Tuple[int, int, int, int],
) -> ImageType:
    font = ImageFont.truetype(font_filepath, size=font_size)

    img = Image.new("RGBA", font.getmask(text).size)

    draw = ImageDraw.Draw(img)
    draw_point = (0, 0)

    draw.multiline_text(draw_point, text, font=font, fill=color)

    text_window = img.getbbox()
    img = img.crop(text_window)

    return img

您可以使用getmask()函數來獲取與給定文本大小完全相同的灰度位圖。

然后,您可以創建一個具有所需背景顏色的空圖像。

然后使用帶有純色和蒙版的im.paste()來繪制文本:


from PIL import Image, ImageFont

text = "Hello world!"
font_size = 36
font_filepath = "/Library/Fonts/Artegra_Sans-600-SemiBold-Italic.otf"
color = (67, 33, 116, 155)

font = ImageFont.truetype(font_filepath, size=font_size)
mask_image = font.getmask(text, "L")
img = Image.new("RGBA", mask_image.size)
img.im.paste(color, (0, 0) + mask_image.size, mask_image)  # need to use the inner `img.im.paste` due to `getmask` returning a core
img.save("yes.png")

感謝@HitLuca 和@AKX 提供上面的代碼示例。 我發現 getmask 函數正在裁剪我的一些文本。 我發現使用 getsize_multiline 函數來獲取文本尺寸作為替代方法效果很好。 下面是我的代碼。

from PIL import Image, ImageFont, ImageDraw, ImageColor

def text_to_image(
text: str,
font_filepath: str,
font_size: int,
color: (int, int, int), #color is in RGB
font_align="center"):

   font = ImageFont.truetype(font_filepath, size=font_size)
   box = font.getsize_multiline(text)
   img = Image.new("RGBA", (box[0], box[1]))
   draw = ImageDraw.Draw(img)
   draw_point = (0, 0)
   draw.multiline_text(draw_point, text, font=font, fill=color, align=font_align)
   return img

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM