Claudiu Claudiu - 9 months ago 32
Python Question

why is my truetype font of size 11 rendering different than windows?

To wit: Notepad is opened, the font selected as "Arial, Size 11", the words "this is just a test" carefully entered, a screenshot taken:


The following Python code is entered and run:

import ImageFont, ImageDraw, Image
im ="c:/textimg.png") #the above image

pilfont = ImageFont.truetype("arial.ttf", 11)

compimg ="RGB", im.size, (255, 255, 255))
draw = ImageDraw.Draw(compimg)

draw.text((0,0), "this is just a test", (0,0,0), font=pilfont)"c:/compimg.png")

Yet the result is disappointingly different:


Not only is it the wrong size, but it's also slightly shaded, whereas the notepad rendering is crisp and crosses no pixel boundaries.

How can I get it to render like notepad does? I've had this exact issue with pygame as well, so I think I'm missing some fundamental understanding about TTF here.

UPDATE: I tried it with pygame again. It does the same thing. It does have an option to turn off anti-aliasing but it looks like it just lops off whatever pixels it would have antialiased based on some threshold. The closest approximation I got was using size 15. The code was:

pygfont = pygame.font.Font(r"c:\windows\fonts\arial.ttf", 15)
surf = pygfont.render("this is just a test", False, (0,0,0), (255,255,255)), r"c:\pygameimg.png")

and the result (notepad original on top for comparison):


Gah why can't I offer a bounty right away?

UPDATE: here's comparing all the methods:


PIL 15, then notepad 11, then pygame 15 anti-alias-off, then pygame 15 anti-alias-on.

PIL 15 actually has the right proportions, it's just anti-aliased. so: why 15 vs. 11? how to make it do it the same way windows does? (and wtf is pygame doing?)

Answer Source

Font rendering is a complex and subtle process, and one that has been implemented a number of times. In your case, PIL and Windows look different because they are using completely different font rendering engines. Windows uses its built-in rendering, and PIL is using the Freetype it was compiled with.

I don't know how each environment interprets its "size" parameter, but even if you get them interpreted the same, the rendering will simply be different. The way to get the same pixels as Notepad is to launch Notepad and grab the screen.

Perhaps if you explain more about why you want the same rendering as Notepad, we'll have creative solutions to your problem.