Center Text of Different Fonts and Sizes?
Closed this issue · 5 comments
Any suggestions on how to center text on the screen no matter the font or text size or font size? I've been fiddling around for a while and can't quite nailed it.
Use the functions from the PIL library to get the size of the text and position the text box accordingly.
See e.g. https://levelup.gitconnected.com/how-to-properly-calculate-text-size-in-pil-images-17a2cc6f51fd
Again, thanks Ton! This is some coding I had been googling but never found. It is close to what I'd written myself. I'm pretty proud of that! :) However, I learned about ImageFont.truetype
from the example. Unfortunately, I still can't get it to center on the screen. Here's what I distilled from the example and the text is no where near center:
from PIL import ImageFont
from papirus import PapirusTextPos
from datetime import datetime
Font = '/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf'
TheSize = 28
# Want today's date displayed, this stuff'll do it.
# Example: Wed, Apr. 28 9:34AM
FMT = '%a, %b. %d %-I:%M %p'
DaDate = datetime.now().strftime(FMT)
DaLine = ImageFont.truetype(Font, TheSize)
line_width = DaLine.getmask(DaDate).getbbox()[2]
x = ((264-line_width) // 2)
print DaDate, x, line_width
text = PapirusTextPos(False)
text.AddText(DaDate, x, 35, fontPath=Font, Id="DaDate")
text.WriteAll()
I thought my screen size was 264x176 but using that width doesn't work. Width seems to depend on the font used and the text included. Help?
You have to take the screen width into account. The text is too wide when using size 28.
You have to reduce the font size until it fits on the display.
The width and height of the display are available.
Here is my version:
#!/usr/bin/python3
from PIL import ImageFont
from papirus import PapirusTextPos
from datetime import datetime
Font = '/usr/share/fonts/truetype/freefont/FreeMonoBold.ttf'
TheSize = 28 # Initial size
text = PapirusTextPos(False)
# Get display size
disp_width = text.papirus.width
disp_height = text.papirus.height
print('disp_width = ', disp_width, ' disp_height = ', disp_height)
# Want today's date displayed
# Example: Wed, Apr. 28 9:34AM
format = '%a, %b %d %-I:%M %p'
theDate = datetime.now().strftime(format)
print(theDate)
# Decrease font size until date fits on display
max_width = disp_width - 4 # Leave some margin
line_width = disp_width
TheSize += 1
while line_width > max_width:
dateFont = ImageFont.truetype(Font, TheSize)
bbox = dateFont.getmask(theDate).getbbox()
print('bbox = ', bbox)
line_width = bbox[2] - bbox[0]
TheSize -= 1
line_height = bbox[3] - bbox[1]
print('line_width = ', line_width, ' line_height = ', line_height)
# Center date
x = (disp_width - line_width) // 2
y = (disp_height - line_height) // 2
print('x = ', x, ' y = ', y)
# Show it
text.AddText(theDate, x, y, size=TheSize, fontPath=Font, Id="theDate")
text.WriteAll()
Here the output for a 2.7" (264 x 176) and a picture:
pi@papirus-test:~ $ python3 txtpostest.py
disp_width = 264 disp_height = 176
Sat, May 01 8:38 PM
bbox = (2, 0, 325, 25)
bbox = (2, 0, 324, 24)
bbox = (2, 0, 305, 23)
bbox = (2, 0, 305, 22)
bbox = (2, 0, 286, 21)
bbox = (2, 0, 267, 20)
bbox = (2, 0, 267, 19)
bbox = (2, 0, 248, 18)
line_width = 246 line_height = 18
x = 9 y = 79
pi@papirus-test:~ $
and for a 2.0" (200x96):
pi@papirus-test:~ $ python3 txtpostest.py
disp_width = 200 disp_height = 96
Sat, May 01 8:46 PM
bbox = (2, 0, 325, 25)
bbox = (2, 0, 324, 24)
bbox = (2, 0, 305, 23)
bbox = (2, 0, 305, 22)
bbox = (2, 0, 286, 21)
bbox = (2, 0, 267, 20)
bbox = (2, 0, 267, 19)
bbox = (2, 0, 248, 18)
bbox = (2, 0, 248, 17)
bbox = (2, 0, 229, 17)
bbox = (2, 0, 210, 16)
bbox = (2, 0, 210, 16)
bbox = (2, 0, 191, 14)
line_width = 189 line_height = 14
x = 5 y = 41
pi@papirus-test:~
That was excellent. Thank you. I can't believe I blew it because of the size.
Closing the issue