通过字体名称而不是文件名选择PIL.ImageFont,并且跨平台字体

问题描述 投票:0回答:3

ImageFont.truetype
需要文件名才能工作,例如:

font = ImageFont.truetype("ariblk.ttf")  # Arial Black

有没有办法使用

PIL
来按名称而不是文件名加载字体?

上下文:我想加载粗体(粗重)无衬线字体,该字体可以在任何平台 Windows、Linux、Mac 上使用。

我认为

ImageFont.truetype("ariblk.ttf")
不能跨平台工作,是否可以使用
ImageFont.truetype("Arial Black")
加载它,或者更好的是,可以在所有平台上使用
ImageFont.truetype("sans-serif;bold")

python fonts python-imaging-library
3个回答
13
投票

看Pillow的

ImageFont
模块的文档,没有这个选项,没有。

一个方便的解决方法可能是使用 Matplotlib 的

font_manager
模块: 用于跨平台查找、管理和使用字体的模块。 使用
FontProperties
findfont
,你应该得到具有给定属性的字体的有效路径,然后您可以在公共
ImageFont.truetype
调用中使用该路径。

这是一个小例子,它在我的 Windows 机器上运行得很好。不幸的是,我附近没有任何其他操作系统可供测试。

from matplotlib import font_manager
from PIL import Image, ImageDraw, ImageFont

font = font_manager.FontProperties(family='sans-serif', weight='bold')
file = font_manager.findfont(font)
print(file)

img = Image.new('RGB', (400, 300), (255, 255, 255))
draw = ImageDraw.Draw(img)

font = ImageFont.truetype(file, 48)
draw.text((20, 20), 'Hello World', font=font, fill=(255, 0, 0))

img.save('test.png')

print
输出:

...\Lib\site-packages\matplotlib\mpl-data\fonts\ttf\DejaVuSans-Bold.ttf

图像输出:

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Matplotlib:    3.3.4
Pillow:        8.1.0
----------------------------------------

0
投票

HansHirse 的最佳答案非常棒,但只是为了为仍在寻找的人添加它,您还可以使用 matplotlib.font_manager 来查找特定字体:

from matplotlib import font_manager

#print all available fonts 
print(font_manager.get_font_names())


#Find the path for a specific font:
file = font_manager.findfont('Helvetica Neue')

#Load the font to pillow
font = ImageFont.truetype(file, 20)

#draw text onto image using pillow:
draw.text((20, 20), 'Hello World', font=font, fill=(0, 0, 0))

如果您特别担心字体在其他系统上不可用,但又想保留默认值,您可以尝试组合这些字体...除了...原因:

try:
    file = font_manager.findfont('Helvetica Neue')
    font = ImageFont.truetype(file, fontsize)
except:
    font_search = font_manager.FontProperties(family='sans-serif', weight='normal')
    file = font_manager.findfont(font_search)
    font = ImageFont.truetype(file, fontsize)

这样您就可以确信您可以获得默认字体或类似字体(如果不可用)。


0
投票

您可以使用SimPILFont

基本用法
from simpilfont import SimPILFont, FONTMAP

#load .ttf files from a font directory and all sub-directories
FONTMAP(fontdir='path/to/fonts') 

text = "Hello World"

#load font
sf  = SimPILFont('DejaVu Sans 22 condensed bold oblique')

#get ImageFont
ttf = sf.font

#measure text
x,y,w,h = sf.bbox(text)

img  = Image.new("RGB", (w-x, h-y), color="black")
dctx = ImageDraw.Draw(img)

dctx.text((-x, -y), text, font=ttf, fill="white")

img.show()
del dctx
© www.soinside.com 2019 - 2024. All rights reserved.