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

自古美人都是妖i 提交于 2019-11-30 21:54:48

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.

I think Notepad's "size" is pointsize and ImageFont.truetype()'s "size" is pixels.

Mark Ransom

The sizes are coming out different because they're specified differently. To convert points to pixels, use the formula: pixels = points * 96 / 72 where 96 is the DPI configured into Windows (not the actual DPI of the monitor). In your case, 11*96/72 = 14.6666, which rounds to 15.

As for making the text pixel-for-pixel identical, that will be impossible with the tools provided - Ned is correct. If this is absolutely vital, you'll need to use the Windows API to render this text for you and copy it into the image. Not a simple process.

Claudiu

Success - look at the red line:

praise the lord http://i54.tinypic.com/2r60dc3.png

Using the method I created here.

Interestingly, I still had to supply the font size 15. I'm not sure if this is point vs. pixel related, though, as the docs say:

> 0: The font mapper transforms this value into device units and matches it against the cell height of the available fonts.

< 0: The font mapper transforms this value into device units and matches its absolute value against the character height of the available fonts.

However, supplying -11 didn't get the desired result... it just made it smaller.. so I have no clue. It's probably point vs. pixel.

As Ned already pointed out, it is not very correct to try to get same result from some rendering library. If you want exactly the same native look, you try to get to Windows' internal functionality, and that is what you already done as I see from your other post, and it is very interesting.

If we speak of realistic text rendering for screen in general, there are some improtant nuances. First, all vector font formats are not initially developed for screen, but merely for typography, and its two big differences. For screen, all you need is a bitmap, namely 8-bit alpha channel information which you then blend to the screen background together with pixel values. To get things working you need literally to rip the TTF file into a set of bitmaps.

And here are two ways to go, roughly speaking:

  • Extract glyphs at high resolution in BW (1-bit). E.g. ~600px bitmaps would be enough for most cases. Then you can construct and resize strings, depending on needs.

  • Extract them directly to the target resolution as 8-bit arrays. In this case you cannot resize them, but only construct strings simply putting this 8-bit arrays in alpha channel and placing along the line.

In both cases you need also exact distance list and kerning pairs list, which is obviously different for each target resolution and extracting this information can vary for different font formats.

It is better to stick to first step, because the second approach you can achieve from high-res bitmaps as well, no need to rasterize it each time. For small sizes for better distance accuracy you can also generate "shifted" glyphs, that means same glyphs, but shifted in 1/2 or 1/3 pixel in initial high-res image. This again would require slightly different string construct procedure.

Important note about the size: there is no such precise thing as size of the font. In typography this is the size of Em square and does not have direct connection with x-height of the font. Moreover, if I do bitmap rendering or resampling, I only operate with pixel-size of the Em-square (boundaries of whole bitmap) and downsampling factor, if I use it to get to small bitmaps. Real x-height size can be approximatly calculated only for reference.

For your case of non-antialiased bitmaps, these small bitmaps must be already included in font file, at least for native fonts like Arial and Times. IIRC Those are stored inside TTF for particular small sizes 7 - 16 pt usually, and as 1-bit masks. The only question is how to extract or get to them them from an application. I don't know really, I see those merely as legacy stuff. I am more in realistic rendering problematics.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!