Прямоугольники вместо текста при использовании нестандартных шрифтов
Мне нужно вставлять имена пользователей на изображение, порой у них бывают имена с "нестандартными" шрифтами, из-за чего вместо текста появляются прямоугольники. Смена шрифта не помогла.
Вот код:
from PIL import Image, ImageFont, ImageDraw
import discord
size_card = (885, 215)
сolor_card = (30, 30, 30)
font3 = ImageFont.truetype("files/img/calibri.ttf", 38)
card = Image.new("RGB", size_card, color_card)
draw = ImageDraw.Draw(card)
user = discord.Member
draw.text((239, 98), f"{str(user.name)} #{str(user.discriminator)}", (255, 255, 255), font=font3)
Ответы (2 шт):
Ваш код работает правильно:
from collections import namedtuple
from PIL import Image, ImageFont, ImageDraw
User = namedtuple('User', 'name discriminator')
user = User(name="Jonh", discriminator=123)
size_card = (885, 215)
color_card = (30, 30, 30)
font3 = ImageFont.truetype("files/img/calibri.ttf", 38)
card = Image.new("RGB", size_card, color_card)
draw = ImageDraw.Draw(card)
draw.text((239, 98), f"{str(user.name)} #{str(user.discriminator)}", (255, 255, 255), font=font3)
card.show()
PS для воспроизведения, я создал объект user с типом namedtuple с соответствующими полями
результат:
UPD: вырезка из docstring для метода ImageFont.truetype(font, size, ...):
:param font: A filename or file-like object containing a TrueType font. If the file is not found in this filename, the loader may also search in other directories, such as the :file:`fonts/` directory on Windows or :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on macOS.
Т.е. в качестве значения в параметр font вы должны передавать либо путь к файлу шрифта в OS либо file-object (указатель на открытый файл шрифта).
Немного ошибок терминологии: То что вы называете "шрифтами", является символами Unicode'а.
В вашем случае, шрифт (*.ttf-файл, в данном случае), не поддерживает указанных вами символов юникода (А если быть точнее - полноширинных символов).
Либо поменяйте шрифт на поддерживающий необходимые символы, либо проверяйте каждый символ на наличие в шрифте, и в случае его отсутствия, берите символ из другого шрифта. Например, через библиотеку fonttools:
def char_in_font(unicode_char, font):
for cmap in font["cmap"].tables:
if cmap.isUnicode():
if ord(unicode_char) in cmap.cmap:
return True
return False
check_font = TTFont(font_path) # font_path - путь к файлу шрифта на диске
for c in your_string:
if char_in_font(c, check_font):
... # рисуем символ стандартным шрифтом
else:
... # рисуем символ "аварийным" шрифтом
В качестве "аварийного" шрифта могу посоветовать Symbola
