Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL cuts off top of letters

I've spent a lot of time making my first web application using Python, and I'm using pil for generating images. After reading a lot, I've managed to implement proper text aligning, wrapping, generating files with many extensions etc.

However, all the text generated by PIL is cut off at the top. Here's a sample.

Example of PIL-generated image with text cut off at the top

It should say ŻÓĆjygpq in a variety of fonts (the font names are on the left).

I've found few posts here: fonts clipping with PIL, but I'd like to avoid using another module (aggdraw); since I've figured out so many things in PIL already I'd like to stick to that.

I've tried many fonts in different sizes, but text is still cut off. I even tried to use PIL fonts, but it still doesn't work. [Also converting OTF to BDF, and to PIL].

This is on Ubuntu. What should I try next?

like image 942
Matt Avatar asked Dec 11 '12 14:12

Matt


1 Answers

I hope to be wrong on this one, but the only correct fix relies on patching how _imagingft.c renders the text. PIL depends on FreeType for this task, but PIL seems to be miscalculating the positioning. Also, the height in getsize is overestimated (although that doesn't cause problem). For the moment, I've put a patch to handle these issues at: http://pastebin.com/jP2iLkDN (there seems to be a better way to patch the render code).

Here are some examples of the output I get without the patch and with the patch, respectively:

enter image description here     enter image description here

Results using the code present in the linked discussion. On OSX:

enter image description here     enter image description here

On Ubuntu:

enter image description here     enter image description here

Here is the code to generate the top figures:

# -*- encoding: utf8 -*-
import sys
import Image, ImageDraw, ImageFont

im = Image.new("RGBA", (1000, 1000), 'white')
draw = ImageDraw.Draw(im)

start_y = 7
text = u'\u00d1\u00d3yŻ\u00d4Ćgp\u010c\u0137'
for i in xrange(28, 46, 2):
    font = ImageFont.truetype('Junicode-Bold.ttf', i)
    width, height = font.getsize(text)
    draw.rectangle((0, start_y, width, height + start_y), outline='blue')
    draw.text((0, start_y), text, font=font, fill='black')
    start_y += height + 7

im.crop((0, 0, width + 1, start_y + 2)).save(sys.argv[1])

The bottom figures were generated according to code present in the linked topic about PIL cutting off parts of the text.

like image 178
mmgp Avatar answered Oct 11 '22 03:10

mmgp