-
Notifications
You must be signed in to change notification settings - Fork 0
/
font.py
70 lines (52 loc) · 2.41 KB
/
font.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Mostly stolen from StackOverflow (text colour customisation added)
# https://stackoverflow.com/questions/11993290/truly-custom-font-in-tkinter/73428832#73428832
# Thanks to just_a_kid_coder_123 for this answer!
from PIL import Image, ImageFont, ImageDraw
def hex_to_tuple(colour_code: str):
if len(colour_code) != 7: raise ValueError(f"Invalid colour code {colour_code}")
colour_code = colour_code.removeprefix("#")
split_colour = [colour_code[i:i+2] for i in range(0, 6, 2)]
for i in range(len(split_colour)):
split_colour[i] = int(split_colour[i], 16)
return tuple(split_colour)
class RenderFont:
def __init__(self, filename):
"""
constructor for RenderFont
filename: the filename to the ttf font file
fill: the color of the text
"""
self._file = filename
self._image = None
def get_render(self, font_size, txt, type_="normal", colour = (255, 255, 255), align = "mm"):
"""
returns a transparent PIL image that contains the text
font_size: the size of text
txt: the actual text
type_: the type of the text, "normal" or "bold"
"""
if type(txt) is not str:
raise TypeError("text must be a string")
if type(font_size) is not int:
raise TypeError("font_size must be a int")
if type(colour) is not tuple:
colour = hex_to_tuple(colour)
width = len(txt)*font_size
height = (font_size+5) * ("\n".count(txt) + 20)
font = ImageFont.truetype(font=self._file, size=font_size)
self._image = Image.new(mode='RGBA', size=(width, height), color=(255, 255, 255))
rgba_data = self._image.getdata()
newdata = []
for item in rgba_data:
if item[0] == 255 and item[1] == 255 and item[2] == 255:
newdata.append((255, 255, 255, 0))
else:
newdata.append(item)
self._image.putdata(newdata)
draw = ImageDraw.Draw(im=self._image)
if type_ == "normal":
draw.text(xy=(width/2, height/2), text=txt, font=font, fill=colour, anchor=align)
elif type_ == "bold":
draw.text(xy=(width/2, height/2), text=txt, font=font, fill=colour, anchor=align,
stroke_width=1, stroke_fill=colour)
return self._image