#πŸ”’ how do you add text to a image with pillow?

157 messages Β· Page 1 of 1 (latest)

late herald
#

tried
ImageDraw.Draw(unique_filename).text((28, 36), self.test.value, fill=(255, 0, 0))

sour craterBOT
#

@late herald

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

wide marsh
#

you need to create a separate draw object first by passing in your original image so you can draw on it

#

think of it like putting a sheet of glass over your image that you can then draw on

late herald
#

this?

#

bc i get error

wide marsh
#

What does the error say?

late herald
#

how can i use a defult font

#

or one i have installed with windows already

#

or smth

wide marsh
#

hmm it should be able to pull from installed fonts

late herald
wide marsh
#

can you show the font in your windows Fonts folder?

late herald
#

@wide marsh

#
[2024-10-29 16:11:01] [ERROR   ] discord.ui.modal: Ignoring exception in modal <BarcodeInputModal timeout=None children=2>:
Traceback (most recent call last):
  File "C:\Users\littl\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\ui\modal.py", line 189, in _scheduled_task
    await self.on_submit(interaction)
  File "C:\Users\littl\OneDrive\Documents\test", line 82, in on_submit
    I1.text((10, 250), "test", font=ImageFont.truetype('ARIALBD.ttf', 65), fill=(255, 0, 0))
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\littl\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFont.py", line 1008, in truetype
    return freetype(font)
           ^^^^^^^^^^^^^^
  File "C:\Users\littl\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFont.py", line 1005, in freetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\littl\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\ImageFont.py", line 255, in __init__
    self.font = core.getfont(
                ^^^^^^^^^^^^^
OSError: cannot open resource```
wide marsh
#

Yes, I'm saying that it cannot find the font

late herald
late herald
wide marsh
#

sure you can try that

late herald
#

I1.text((10, 250), "test", font=ImageFont.truetype('ARIALBD.ttf', 65), fill=(255, 0, 0))

#

to

#

I1.text((10, 250), "test", font=ImageFont.truetype('C:\\WINDOWS\\FONTS\\ARIALBD.ttf', 65), fill=(255, 0, 0))

late herald
wide marsh
#

try it and see

late herald
late herald
#

@wide marsh is there a way to wrap text automatilly if it goes off the image?

wide marsh
#

!e

import textwrap


message = 'this is a really long message and I want it to wrap around'
print(textwrap.fill(message, width=16))
sour craterBOT
late herald
#

so i can increase the starting poistion for the text

wide marsh
#

there's a text bbox method for getting the size of the resulting text

#

then you need to do a bit of math to offset it based on that

late herald
#

ohh

#

just .len

#

the do mod

wide marsh
#

you can do draw.textbbox

#

it won't actually perform the drawing, but it will give you the resulting bounding box as if it were to add the text

late herald
#

draw isnt defined tho

#
message = textwrap.fill(self.value, width=16)
amount = draw.textbbox(message)
I1.text((38, (50 * amount) + 910)), textwrap.fill(message, width=16), font=ImageFont.truetype('C:\\WINDOWS\\FONTS\\ARIALBD.ttf', 40), fill=(0, 0, 0))```
#

this?

wide marsh
#

draw should be your draw object

#

I1 in your case

#

you also need to give it a starting position and your font

late herald
wide marsh
#

not to the textbbox you didn't

#

it returns a tuple of your top, left, bottom, right

#

so you can use these values to work out how to center the text based on your canvas and text size

late herald
wide marsh
#
bbox = draw.textbbox((0, 0), fit_text, font=font)
text_width = (bbox[2] - bbox[0])
text_height = (bbox[-1] - bbox[1])
mid_x = (bbox[0] + bbox[2]) // 2
mid_y = (bbox[-1] + bbox[1]) // 2
x_placement = (size[0] // 2) - abs(mid_x - text_width)
y_placement = (size[1] // 2) - abs(mid_y - text_height)
#

here's an example from one of my previous works

#

size is the total size of my image

#

here's a result

late herald
# wide marsh `size` is the total size of my image

okay so this?

                draw = ImageDraw.Draw(base_image)
                bbox = draw.textbbox((38, 910), self.value, font=ImageFont.truetype('C:\\WINDOWS\\FONTS\\ARIALBD.ttf', 25))
                text_width = (bbox[2] - bbox[0])
                text_height = (bbox[-1] - bbox[1])
                mid_x = (bbox[0] + bbox[2]) // 2
                mid_y = (bbox[-1] + bbox[1]) // 2
                x_placement = (604[0] // 2) - abs(mid_x - text_width)
                y_placement = (1334[1] // 2) - abs(mid_y - text_height)```
#

what do i do with x_placement and y_placement

#

and the bbox varible that potision should be my starting poitstion right?

wide marsh
#
draw.text((x_placement, y_placement),
          fit_text,
          fill='black',
          font=font,
          align='center')
late herald
#

and then it will move up right

wide marsh
#

ahh sorry, forgot the final line

#

don't just blindly copy what I have. Follow the steps and apply it to your own data

#

(604[0] // 2)

#

indexing an int doesn't make sense here

#

my fit_text is my text after being modified by textwrap.fill

late herald
wide marsh
#

you can always get the size of your image using base_image.size

#

so you can do size = base_image.size

late herald
late herald
#

604,1334

wide marsh
#
fit_text = textwrap.fill(self.text, width=MAX_TEXT_WIDTH)
wide marsh
wide marsh
#

no

#

get rid of the [0]

late herald
wide marsh
#

you can't index ints

late herald
wide marsh
#

I really recommend making variables for this so you aren't using "random" numbers

#

it makes it so much easier to make changes if needed

late herald
#

so now its in a strange poisition

late herald
#

i want the last line

#

to be at x=38 y=910

#

not cenetered

wide marsh
#

then that's not going to be the same math

late herald
#

the fit text

wide marsh
#

you don't need to, you only need to know the height which you get from the bbox

wide marsh
#

just don't divide the mid_y by 2

#

dividing by 2 is centering

late herald
#

bc that still puts it randomly

#

i dont need to change x

#

just the last y line should be 910

wide marsh
#

you should be able to nudge it down by half the text height

#

if it's already centered

late herald
wide marsh
#

I'm saying if you already have it centered

late herald
#

ohh

wide marsh
#

let's say this is your window

late herald
late herald
wide marsh
#

and the red box is where your text currently is

late herald
#

yes

wide marsh
#

you know the height of your window, and you know the height of your text box

wide marsh
#

you can get the size of this space

#

center point + half height of the text box

#

that gets you the bottom

#

and then you have to get the difference between the image size and the bottom

late herald
late herald
#

okay

#

so

#

mid_y + (bbox / 2) = red box

#

but then how do i get that to the 910

#

x

wide marsh
#

get the difference between 910 and your image height

#

and subtract that from the result

wide marsh
#

you want text_height // 2

late herald
#

and then how do i get the last row to equal 910

#

using this

late herald
#

910 - (mid_y + (text_height // 2))

#

will get me where i want it to be?

wide marsh
#

no, you need the difference between 910 and your image height

late herald
wide marsh
#

base_image.size[0] - 910

#

I don't see that anywhere

#

and it should be subtracted from the result, not the other way around

late herald
#

Ohh

#

And that will get me my y position?

wide marsh
#

focus on just getting it flush with the bottom of the screen first, then worry about the offset to 910 after

wide marsh
late herald
#

And that’s with the code you sent me

#

But -0?

wide marsh
#

can you show me what your image looks like?

sour craterBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.