Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

430
Visualizações
How to get the font pixel height using PIL's ImageFont class?

I am using PIL' ImageFont module to load fonts to generate text images. I want the text to tightly bound to the edge, however, when using the ImageFont to get the font height, It seems that it includes the character's padding. As the red rectangle indicates.enter image description here

c = 'A'
font = ImageFont.truetype(font_path, font_size)
width = font.getsize(c)[0]
height = font.getsize(c)[1]
im = Image.new("RGBA", (width, height), (0, 0, 0))
draw = ImageDraw.Draw(im)
draw.text((0, 0), 'A', (255, 255, 255), font=font)
im.show('charimg')

If I can get the actual height of the character, then I could skip the bounding rows in the bottom rectangle, could this info got from the font? Thank you.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Exact size depends on many factors. I'll just show you how to calculate different metrics of font.

font = ImageFont.truetype('arial.ttf', font_size)
ascent, descent = font.getmetrics()
(width, baseline), (offset_x, offset_y) = font.font.getsize(text)
  • Height of red area: offset_y
  • Height of green area: ascent - offset_y
  • Height of blue area: descent
  • Black rectangle: font.getmask(text).getbbox()

Hope it helps.

over 4 years ago · Santiago Trujillo Relatório

0

The top voted answer is outdated. There is a new function in Pillow 8.0.0: ImageDraw.textbbox. See the release notes for other text-related functions added in Pillow 8.0.0.

Note that ImageDraw.textsize, ImageFont.getsize and ImageFont.getoffset are broken, and should not be used for new code. These have been effectively replaced by the new functions with a cleaner API. See the documentaion for details.

To get a tight bounding box for a whole string you can use the following code:

from PIL import Image, ImageDraw, ImageFont
image = Image.new("RGB", (200, 80))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("arial.ttf", 30)

draw.text((20, 20), "Hello World", font=font)
bbox = draw.textbbox((20, 20), "Hello World", font=font)
draw.rectangle(bbox, outline="red")
print(bbox)
# (20, 26, 175, 48)

image.show()

bounding box example


You can combine it with the new ImageDraw.textlength to get individual bounding boxes per letter:


from PIL import Image, ImageDraw, ImageFont
image = Image.new("RGB", (200, 80))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("arial.ttf", 30)

xy = (20, 20)
text = "Example"
draw.text(xy, text, font=font)

x, y = xy
for c in text:
  bbox = draw.textbbox((x, y), c, font=font)
  draw.rectangle(bbox, outline="red")
  x += draw.textlength(c, font=font)

image.show()

letter bounding boxes example

Note that this ignores the effect of kerning. Kering is currently broken with basic text layout, but could introduce a slight inaccuracy with Raqm layout. To fix it you would add the text length of pairs of letters instead:

for a, b in zip(text, text[1:] + " "):
  bbox = draw.textbbox((x, y), a, font=font)
  draw.rectangle(bbox, outline="red")
  x += draw.textlength(a + b, font=font) - draw.textlength(b, font=font)
over 4 years ago · Santiago Trujillo Relatório

0

from PIL import Image, ImageDraw, ImageFont

im = Image.new('RGB', (400, 300), (200, 200, 200))
text = 'AQj'
font = ImageFont.truetype('arial.ttf', size=220)
ascent, descent = font.getmetrics()
(width, height), (offset_x, offset_y) = font.font.getsize(text)
draw = ImageDraw.Draw(im)
draw.rectangle([(0, 0), (width, offset_y)], fill=(237, 127, 130))  # Red
draw.rectangle([(0, offset_y), (width, ascent)], fill=(202, 229, 134))  # Green
draw.rectangle([(0, ascent), (width, ascent + descent)], fill=(134, 190, 229))  # Blue
draw.rectangle(font.getmask(text).getbbox(), outline=(0, 0, 0))  # Black
draw.text((0, 0), text, font=font, fill=(0, 0, 0))
im.save('result.jpg')

print(width, height)
print(offset_x, offset_y)
print('Red height', offset_y)
print('Green height', ascent - offset_y)
print('Blue height', descent)
print('Black', font.getmask(text).getbbox())

result

Calculate area pixel

from PIL import Image, ImageDraw, ImageFont

im = Image.new('RGB', (400, 300), (200, 200, 200))
text = 'AQj'
font = ImageFont.truetype('arial.ttf', size=220)
ascent, descent = font.getmetrics()
(width, height), (offset_x, offset_y) = font.font.getsize(text)
draw = ImageDraw.Draw(im)
draw.rectangle([(0, offset_y), (font.getmask(text).getbbox()[2], ascent + descent)], fill=(202, 229, 134))
draw.text((0, 0), text, font=font, fill=(0, 0, 0))
im.save('result.jpg')
print('Font pixel', (ascent + descent - offset_y) * (font.getmask(text).getbbox()[2]))

result

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda