Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL how to scale text size in relation to the size of the image

I'm trying to dynamically scale text to be placed on images of varying but known dimensions. The text will be applied as a watermark. Is there any way to scale the text in relation to the image dimensions? I don't require that the text take up the whole surface area, just to be visible enough so its easily identifiable and difficult to remove. I'm using Python Imaging Library version 1.1.7. on Linux.

I would like to be able to set the ratio of the text size to the image dimensions, say like 1/10 the size or something.

I have been looking at the font size attribute to change the size but I have had no luck in creating an algorithm to scale it. I'm wondering if there is a better way.

Any ideas on how I could achieve this?

Thanks

like image 441
Shpongle Avatar asked Feb 04 '11 19:02

Shpongle


People also ask

How can I tell the size of text in an image?

Once the text in the word processor looks like the text in the image, simply look at the font size that you're using in the word processor and that will be the font size that was used to create the image.

How do you scale text?

Users can adjust text scale with the Make text bigger slider on the Settings -> Ease of Access -> Vision/Display screen.

How do you find the text size in Python?

Python has a method called len() that gives us the length of any composite object. To get the length of a string, just pass the string to the len() call.


2 Answers

You could just increment the font size until you find a fit. font.getsize() is the function that tells you how large the rendered text is.

from PIL import ImageFont, ImageDraw, Image  image = Image.open('hsvwheel.png') draw = ImageDraw.Draw(image) txt = "Hello World" fontsize = 1  # starting font size  # portion of image width you want text width to be img_fraction = 0.50  font = ImageFont.truetype("arial.ttf", fontsize) while font.getsize(txt)[0] < img_fraction*image.size[0]:     # iterate until the text size is just larger than the criteria     fontsize += 1     font = ImageFont.truetype("arial.ttf", fontsize)  # optionally de-increment to be sure it is less than criteria fontsize -= 1 font = ImageFont.truetype("arial.ttf", fontsize)  print('final font size',fontsize) draw.text((10, 25), txt, font=font) # put the text on the image image.save('hsvwheel_txt.png') # save it 

If this is not efficient enough for you, you can implement a root-finding scheme, but I'm guessing that the font.getsize() function is small potatoes compared to the rest of your image editing processes.

like image 75
Paul Avatar answered Sep 21 '22 15:09

Paul


In general when you change the font sizing its not going to be a linear change in size of the font.

Non-linear Scaling

Now this often depends on the software, fonts, etc... This example was taken from Typophile and uses LaTex + Computer Modern font. As you can see its not exactly a linear scaling. So if you are having trouble with non-linear font scaling then I'm not sure how to resolve it, but one suggestion maybe is to.

  1. Render the font as closely to the size that you want, then scale that up/down via regular image scaling algorithm...
  2. Just accept that it won't exactly be linear scaling and try to create some sort of table/algorithm that will select the closest point size for the font to match up with the image size.
like image 37
Pharaun Avatar answered Sep 21 '22 15:09

Pharaun