При использовании объектов tkinter.font.Font
и PIL.ImageFont.FreeTypeFont
я получаю различные значения для измерений текста (например, ширину строки текста в пикселях).
Пример кода (python 3)
import tkinter as tk
from tkinter.font import Font
import shlex, subprocess
import PIL
"""
Get the path of the font to use with PIL
"""
def get_font_path(fname):
command_line = str('fc-match -f "%{file}\n" '+fname)
args = shlex.split(command_line)
p=subprocess.check_output(args, stderr=subprocess.STDOUT)
fontpath = p.decode('UTF-8').splitlines()[0]
print(fontpath)
return fontpath
fname = 'Courier'
fsize = 14
sampletxt = "Am I a beagle?"
fontpath = get_font_path(fname)
pilfont = PIL.ImageFont.FreeTypeFont(font=fontpath, size=fsize)
print(f'width, height: {pilfont.getsize(sampletxt)}')
Выход из вышеуказанного измерения PIL.
/usr/share/fonts/type1/texlive-fonts-recommended/pcrr8a.pfb
width, height: (112, 14)
Пример кода Продолжение ..
"""
The Tkinter measurements
"""
##root = tk.Tk() #Don't need this apparently
tkfont = Font(family="Courier", size=fsize)
print(f'width, height: {(tkfont.measure(sampletxt), tkfont.metrics("linespace"))}')
tkfont.actual()
Выход из приведенного выше измерения Tkinter:
width, height: (168, 17)
{'family': 'gothic',
'size': 14,
'weight': 'normal',
'slant': 'roman',
'underline': 0,
'overstrike': 0}
Эти значения отличаются. Очевидно, tkinter
использует другой шрифт, но откуда? Если заставить Tkinter
использовать тот же шрифт, который указан в объекте PIL
, это можно исправить, но я не могу определить, как tkinter
загружает или использует шрифты.
Я смотрел на этот связанный действительно пользовательский шрифт в tkinter вопрос, но я использую Debian (Ubuntu) не Windows.
Вот еще несколько свойств шрифта tkinter, если они вам помогут.
tkinter.font.families()
## OUTPUT:
('fangsong ti',
'fixed',
'clearlyu alternate glyphs',
'courier 10 pitch',
'open look glyph',
'bitstream charter',
'song ti',
'open look cursor',
'newspaper',
'clearlyu ligature',
'mincho',
'clearlyu devangari extra',
'clearlyu pua',
'clearlyu',
'clean',
'nil',
'clearlyu arabic',
'clearlyu devanagari',
'gothic',
'clearlyu arabic extra')
tkinter.font.names()
##OUTPUT:
('TkCaptionFont',
'TkSmallCaptionFont',
'TkTooltipFont',
'font308',
'TkFixedFont',
'TkHeadingFont',
'font310',
'TkMenuFont',
'TkIconFont',
'TkTextFont',
'TkDefaultFont')
ОБНОВЛЕНИЕ:
Я пытался использовать шрифт Tkinter
, а затем использование соответствующего файла шрифта для создания объекта шрифта PIL FreeType
, и измерения все еще отличаются ...
Я довольно озадачен.
text = "Where are my beards?"
### PIL Measurement ###
# The location of the fontfile corresponding to 'courier 10 pitch'
fontpath = '/usr/share/fonts/X11/Type1/c0419bt_.pfb'
font = ImageFont.FreeTypeFont(font=fontpath, size=80)
im = Image.new("RGBA", (1092, 1456), (0, 0, 0))
draw = ImageDraw.Draw(im)
draw.multiline_text((0,0), text, (255, 255, 255), font=font)
multi_size = draw.multiline_textsize(text, font=font)
print(f"multi size: {multi_size}\n")
w,h = font.getsize_multiline(text)
im.close()
del im
print(f'Width: {w}, Height: {h}\n')
#print font name
print(font.getname())
Выход измерения PIL :
multi size: (960, 69)
Width: 960, Height: 69
('Courier 10 Pitch', 'Regular')
Измерение шрифта Tkinter
fname = 'courier 10 pitch'
font = tkFont.Font(family=fname, size=80)
(w,h) = (font.measure(text),font.metrics("linespace"))
print(f'Width: {w}, Height: {h}\n')
print(f'{ sorted([k, v] for k,v in font.actual().items()) }')
Результат измерения Tkinter:
Width: 1280, Height: 124
[['family', 'courier 10 pitch'], ['overstrike', 0], ['size', 80], ['slant', 'roman'], ['underline', 0], ['weight', 'normal']]
Значение Width: 960, Height: 69
измерения PIL по сравнению с Width: 1280, Height: 124
измерения Tkinter довольно сильно отличается.
Я считаю, что измерение Tkinter является точным, но я не могу полагаться на использование дисплея Tkinter на сервере без монитора (например).
Если я не ошибаюсь, эти два измерения должны быть идентичны, потому что я использовал один и тот же файл шрифта для обоих.
Есть идеи?