15

I am trying to dynamically increase image size with respect to font and text given to draw.text().

Orignal Problem is to create signature image based on name and the font user selects.

Here is my code

from PIL import (Image, ImageDraw, ImageFont,)

width=20
height=20
selected_font='simply_glomrous.ttf'
font_size=30

img = Image.new('RGBA', (width, height), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(selected_font, font_size)
draw.text((0,0), "Adil Malik", (0,0,0), font)
img.save('signature.png')

But i am still having same image size defined in width and height. Can we do dynamically resizing of image based on font and its size ?

Note: This question is opposite to this stackoverflow question

Mahammad Adil Azeem
  • 9,112
  • 13
  • 57
  • 84

4 Answers4

14

Unfortunately, No one able to answer my question.

Basically, You can't set fix width and height while setting the font size. Both are dependent on each other. So if one increase, second one also increases.

So I have come up with another solution. I am just setting the font size and then based on that font size, I am setting width and height.

from PIL import (Image, ImageDraw, ImageFont,)

name = 'Adil Malik'
selected_font='simply_glomrous.ttf'
font_size=30

font = ImageFont.truetype(selected_font, font_size)
font_size = font.getsize(name)

img = Image.new('RGBA', (font_size[0], font_size[0]), (255, 255, 255, 0))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(selected_font, font_size)
draw.text((0,0), name, (0,0,0), font)
img.save('signature.png')
Mahammad Adil Azeem
  • 9,112
  • 13
  • 57
  • 84
  • 2
    What I find especially interesting is that I answered your question five days before your claim: "Unfortunately, No one able to answer my question." – Jonny Morrill Jan 20 '19 at 20:09
4

The functionality you are looking for is the Draw.textsize method which takes a text string and drawing options as input and returns the width and height of the rendered text.

http://effbot.org/imagingbook/imagedraw.htm#tag-ImageDraw.Draw.textsize

You can use the Draw class with an image that has a width and height of zero and then call the method to determine the dimensions of the text you are looking to render. Once you know those dimensions, you can then resize the image accordingly. For example:

from PIL import ImageDraw, ImageFont, Image

# parameters
text = "My Name"
selected_font = "simply_glomrous.ttf"
font_size = 30

# get the size of the text
img = Image.new('RGBA', (0,0), (255, 255, 255, 0))
font = ImageFont.truetype(selected_font, font_size)
draw = ImageDraw.Draw(img)
text_size = draw.textsize(text, font)

# resize and draw
img = img.resize(text_size)
draw.text((0,0), text, (0,0,0), font)
img.save('signature.png')
Jonny Morrill
  • 407
  • 4
  • 6
  • 1
    Hi! thanks for the solution. I tried to use your code but had one minor problem. No texts were showing up. I had to draw = ImageDraw.Draw(img) again after the resize then it worked. maybe the version difference made this problem. – cd80 Mar 30 '21 at 12:06
3

If you can use openCV and numpy, you can

  1. Check the text size using getTextSize
  2. Create a white image using numpy.ones((height, width, 3), np.uint8)*255

  3. Add text to the image using putText,

  4. Save the image using imwrite.

See here and here for references.

Yohai Devir
  • 320
  • 2
  • 10
2

First, you need to get your scales right: You are starting from a font size given in points, which defined to be 1/72 of an inch; those are "real world" scales. The image you are drawing on is defined in pixels. Pixels get a relation to inches/points only if you also define the pixels-per-inch ratio.

So the way you think about the problem is kind of backward: You need to start with the pixels you have (either from the source or the target image) and then compute the appropriate font size. If you want to have the user select a font size, you need to define (or ask for) a target DPI value in order to change between the units of scale involved.

user2722968
  • 13,636
  • 2
  • 46
  • 67