[英]Generate image from given text
我有一個函數,它使用 Pillow 生成給定文本的圖像表示,使用作為輸入text
、 font
、 font_size
和color
。 該函數通過生成一個空的 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.