Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle textsize deprecation warning #6938

Closed
ArthurPains opened this issue Feb 10, 2023 · 4 comments
Closed

How to handle textsize deprecation warning #6938

ArthurPains opened this issue Feb 10, 2023 · 4 comments

Comments

@ArthurPains
Copy link

ArthurPains commented Feb 10, 2023

I'm getting textsize is deprecated, however when I use textbbox or textlength instead, they don't do the same.

After a lot of research, I finally managed to figure out how to recalculate the font size of a text if it doesn't fit in a specific area. But the only way I could do that was using "textsize". I've already tried using textbbox or textlength and I couldn't use them in my function at all. With that, every time the text size needs to decrease, this message appears to me:

DeprecationWarning: textsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use textbbox or textlength instead.
  textwidth, textheight = draw.textsize(text, font)

I would like to know how can I deal with this? Because every time a print appears with this message, it bothers me and also makes it difficult for me to find other errors.

This is my function:

def draw_text_with_size_adjustment(text, region):
    font_size = 40
    font = ImageFont.truetype("Font/OpenSans-Bold.ttf", font_size)
    while True:
        textwidth, textheight = draw.textsize(text, font)
        if textwidth <= region[2] - region[0] and textheight <= region[3] - region[1]:
            break

        font_size -= 1
        font = ImageFont.truetype("Font/OpenSans-Bold.ttf", font_size)

    x = region[0] + (region[2] - region[0] - textwidth) / 2
    y = region[1] + (region[3] - region[1] - textheight) / 2

    draw.text((x, y), text, font=font, fill=(0, 0, 0))

    img.save("text_example.png")
@Yay295
Copy link
Contributor

Yay295 commented Feb 10, 2023

Does draw.textbbox((0,0), text, font, anchor='la') work?

@nulano
Copy link
Contributor

nulano commented Feb 10, 2023

I'm getting textsize is deprecated, however when I use textbbox or textlength instead, they don't do the same.

Yes, the new functions do not return the same results - the old function was broken and returning incorrect values. But I'm curious, you haven't mentioned what exactly is your problem with the new functions?

x = region[0] + (region[2] - region[0] - textwidth) / 2
y = region[1] + (region[3] - region[1] - textheight) / 2

This is not a reliable way to center text (irrespective of how you obtain text width and height), it is preferred to use anchor="mm" instead.


Whether you use textbbox or textlength depends on your needs - use textlength if you wish to e.g. justify text in a paragraph, or textbbox if you wish to fit text in a box (considering both extra width beyond the advance values of the font, as well as vertical height).

Does either of these examples help?

Using font.getlength (equivalent to draw.textlength):

from PIL import Image, ImageDraw, ImageFont

w, h = 300, 100
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."

im = Image.new("RGB", (w, h), "white")
draw = ImageDraw.Draw(im)

font_size = 40
font = ImageFont.truetype(r"C:\Users\Nulano\AppData\Local\Microsoft\Windows\Fonts\OpenSans-Bold.ttf", font_size)

while font_size > 1:
  if font.getlength(text) < w:
    break
  font_size -= 1
  font = font.font_variant(size=font_size)

draw.text((w / 2, h / 2), text, font=font, fill="black", anchor="mm")
im.show()

6938-textlength

Using font.textbbox:

from PIL import Image, ImageDraw, ImageFont

w, h = 300, 100
region = (50, 40, 200, 90)
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."

im = Image.new("RGB", (w, h), "white")
draw = ImageDraw.Draw(im)
draw.rectangle(region, outline="black")

font_size = 40
font = ImageFont.truetype(r"C:\Users\Nulano\AppData\Local\Microsoft\Windows\Fonts\OpenSans-Bold.ttf", font_size)

x = int((region[2] - region[0]) / 2) + region[0]
y = int((region[3] - region[1]) / 2) + region[1]
while font_size > 1:
  bbox = draw.textbbox((x, y), text, font=font, anchor="mm")
  if bbox[0] > region[0] and bbox[1] > region[1] and bbox[2] < region[2] and bbox[3] < region[3]:
    break
  font_size -= 1
  font = font.font_variant(size=font_size)

draw.text((x, y), text, font=font, fill="black", anchor="mm")
im.save(r"E:\6938-textbbox.png")
im.show()

6938-textbbox

6938-textbbox2


If you insist on using font.getsize / draw.textsize, that function is equivalent to

def getsize(...):
  # this function has confusing behaviour and should not be used
  left, top, right, bottom = font.getbbox(...)
  width = right - left  # this value can be confusing
  height = bottom       # this value is clearly wrong
  return width, height

but as you can see from that code, that function most likely does not return the values you expect.

@radarhere radarhere changed the title How to handle: DeprecationWarning: textsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use textbbox or textlength instead. How to handle textsize deprecation warning Feb 11, 2023
@radarhere
Copy link
Member

@ArthurPains did that answer your question?

@ArthurPains
Copy link
Author

ArthurPains commented Feb 16, 2023

@radarhere Sorry for the delay, I was traveling.
@nulano It worked, thank you very much!! The code has also become smaller and more organized. Thank you again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants