Rasterising a TTF font - python

I'm on the Raspberry Pi with a screen attached.
Rather than using X, I'm writing pixel data directly to the frame buffer. I've been able to draw images and primitive shapes, blend, use double buffering, etc...
Where I'm hitting a problem is drawing text. The screen is just a byte array from this level, so I need a way to take the font, size, text, etc. and convert it into a bitmap (actually, a bool[] and width/height would be preferable as it saves additional read/writes.
I have no idea how to approach this.
Things I've considered so far...
Using a fixed-width font and an atlas/spritemap. Should work, I can already read images, however monospaced fonts have limited visual appeal. Also means adding more fonts is arduous.
Using a fixed-width font, an atlas and a mask to indicate where each character is. Would support variable-width fonts, however, scaling would be lossy and it seems like a maintenance nightmare unless I can automate the atlas/mask generation.
Has anyone managed to do anything like this before?
If a library is required, I can live with that but as this is more an exercise in understanding my Pi than it is a serious project, I'd prefer an explanation/tutorial.

Consider using the Cairo graphics library, either for all your graphics, or as a tool to generate the font atlases. Cairo has extensive support for rendering fonts using TTF fonts, as well as for other useful graphics operations.
At a lower level, you could also use the Freetype library to load fonts and render characters from them directly. It's more difficult to work with, though.

Related

How does Photoshop convert type format to a rasterized layer?

I have been thinking of fonts quite recently. I find the whole process of a keystroke converted to a character displayed in a particular font quite fascinating. What fascinates me more is that each character is not an image but just the right bunch of pixels switched on (or off).
In Photoshop when I make a text layer, I am assuming it's like any other text layer in a word processor. There's a glyph attached to a character and that is displayed. So technically it's still not an 'image' so as to speak and it can be treated as a text in a word processor. However, when you rasterize the text layer, an image of the text is created with the font that was used. Can somebody tell me how Photoshop does this? I am assuming there should be a lookup table with the characters' graphics which Photoshop accesses to rasterize the layer.
I want to kind of create a program where I generate an image of the character that I am pressing (in C or Python or something like that). Is there a way to do this?
Adobe currently has publicly accessible documentation for the Photoshop file format. I've needed to extract information from PSD files (about a year ago, but actually the ancient CS2 version of Photoshop) so I can warn you that this isn't light reading, and there are some parts (at least in the CS2 documentation) that are incomplete or inaccurate. Usually, even when you have file format documentation, you need to do some reverse engineering to work with that file format.
Even so, see here for info about the TySh chunk from Photoshop 6.0 (not sure at a quick glance if it's still the current form for text - "type" to Photoshop).
Anyway, yes - text is stored as a sequence of character codes in memory and in the file. Fonts are basically collections of vector artwork, so that text can be converted to vector paths. That can be done either by dealing with the font files yourself, using on operating system call (there's definitely one for Windows, but I don't remember the name, it's bugging me now so I might figure it out later), or using a library.
Once you have the vector form, that's basically Bezier paths just like any other vector artwork, and can be rendered the same way.
Or to go directly from text to pixels, you just ask e.g. Windows to draw the text for you - perhaps to a memory DC (device context) if you don't want to draw to the screen.
FreeType is an open source library for working with fonts. It can definitely render to a bitmap. I haven't checked but it can probably convert text to vector paths too - after all it needs to do that as part of rendering to pixels anyway.
Cairo is another obvious library to look at for font handling and much more, but I've never used it directly myself.
wxWidgets is yet another obvious library to look at, and uses a memory-DC scheme similar to that for Windows, though I don't remember exact class/method names. Converting text to vectors might be outside wxWidgets scope, though.

How to use PIL (pillow) to draw text in any language?

I'm rendering user input text on a background image with Python PIL(I'm using pillow).
the code is simple:
draw = ImageDraw.Draw(im)
draw.text((x, y), text, font=font, fill=font_color)
the problem is, the user may input in any language, how could I determine which font to use?
ps: I know I have to have font files first, so I searched and found Google Noto, downloaded all the fonts, put them in /usr/local/share/fonts/, but these fonts are separated by language, so I still can't load a font that can render all user input texts.
NoTo (which is literally just Adobe's Source Pro fonts with a different name because it's easier for Google to market it that way) isn't a single font, it's a family of fonts. When you go to download them, Google explicitly tells you that there are lots of different versions for lots of different target languages, for the two simple reasons that:
if you need to typeset the entire planet's set of known scripts, there are vastly more glyphs than fit in a single font (OpenType fonts have a hard limit of 65535 glyphs per file due to the fact that glyph IDs are encoded as USHORT fields. And fonts are compositional: the "letter" ℃ can actually be the letter C and the symbol °, so it relies on three glyphs: two real glyphs, and one virtual composition. You run out of space real fast that way) , and
even if a font could fit all the glyphs, the same script may need to be rendered rather different depending on the language it's used for, so even having a single font for both Chinese and Japanese, or for Arabic and Urdu, simply doesn't work. While OpenType fonts can cope with that by being told which variation sets to use, and which compositional rules based on specific language tags, that is the kind of control that works great in InDesign or LaTeX, and is the worst thing for fonts that are going to be used in control-less context (like an Android webview, for instance).
So the proper solution is to grab all the fonts, and then pick the right one based on the {script, language} pair you're generating text for. Is that more complicated than what you're trying to do? Yes. Is it necessary? Equally yes =)

Extract text from screen in python

Is there a library etc for extracting text from a png bitmap screen shot?
It is for a automizer and would (for example) be able to read buttons etc. I've checked Tesseract, but it seems to be made for pictures, not computer screen fonts.
If you're dealing with a small amount of possible matches (i.e.: you want to recognize two or three different buttons), the simplest way is to isolate those in a previous screenshot, save them to individual files, and then use some form of template matching, which is quite easy in opencv.
If, however, you need to actually perform recognition of the button text, you're going to need a OCR engine. Tesseract is a good candidate, if you can get it trained for your font (it's a lengthy process). As you mention, you'll need to do this if you're dealing with a small font, which tesseract is not originally trained to recognize. If you can't, there's a couple other engines usable in python around, like Ocropus

Python text to image generation problems

I'm using PIL to load in various fonts and draw text to images. At the basic level, it all works.
However, I am running into a number of problems such as letters being clipped (mainly cursive or stylistic fonts with lots of tails and such). textsize() does return width/height values, yet letters are still clipped. There also doesn't seem to be methods in PIL to specify larger image sizes for the character generating. Another issue is the vertical spacing. It seems PIL returns large height values for certain fonts and thus the vertical spacing between lines is overly large.
I'm in search of a more advanced font and text handling system than PIL, given its apparent limitations.
I've been researching this a lot over the last week (Google, Python docs, Stackoverflow, etc) and I've seen people recommending to use either Imagemagick or a combination of pango and cairo. However, as much as I've read and searched for these respective technologies I am simply not finding any usable documentation that pertains to what I am trying to do. There are some Python bindings for Imagemagick, but they all seem several years out of date.
Can some of the helpful souls here on SO point me to some tutorials on how to use Pango/Cairo and/or Imagemagick?
The Cairo cookbook has a number of examples for using Cairo, and the Python routines are almost mirror images of the C routines.
I've had some fine results with PyGame, but I don't know if it will necessarily solve your problem.

Recommendations for a simple 2D graphics python library that can output to screen and pdf?

I'm looking for an easy-to-use graphics lib for python that can output to screen as well as pdf. So, I would use code to draw some stuff (simple prims like ovals, rectangles, lines and points) to screen and then when things look good, have it output to pdf.
If you use Tkinter, you can draw on a Canvas widget, then use its .postscript method to save the contents as a PostScript file, which you can convert to PDF using ps2pdf.
postscript(self, cnf={}, **kw)
Print the contents of the canvas to a postscript
file. Valid options: colormap, colormode, file, fontmap,
height, pageanchor, pageheight, pagewidth, pagex, pagey,
rotate, witdh, x, y.
Matplotlib should be able to do it. See event handling here: http://matplotlib.sourceforge.net/examples/event_handling/index.html
You can use the Python Imaging Library for drawing images which can easily be displayed in various UIs, e.g. by displaying a jpg. Then, use ReportLab. Here's an example which shows how to use ReportLab with an image.
I'm not sure what you mean by drawing to "screen", i.e. if you're working with a specific UI toolkit. But if it's acceptable to draw and display PDFs without using an intermediate image (jpg, etc), then you might consider the PyX library, which makes it quite simple to do graphics with PDFs.
You could look into matplotlib, which is mainly for plotting but you could probably do some basic drawing.
Then there is pygame. But I'm not so sure if it can generate a pdf, however you can do 2D graphics with it.
There is something called ReportLab that can generate pdf's. Here is a bunch of tutorials using it.
This is a tricky question, because there are so many libraries available - there is a trade-off between beauty/easiness.
What I've done and works great is to produce the Postscript directly, it is not difficult at all, and you can preview it using Ghostview; converting tyo PDF is trivial (ps2pdf). Learning how to tell Postscript to create lines and circles is extremely simple.
If you want more extensibility, then go to Matplotlib, but beware of the many times when it will "decide for you what looks best" even if you don't like it.
Good luck.
Creating PDFs is always a pain, it doesn't make sense if you do not aim to lose sanity.
With that said, you are aiming to do two completely different things: when you draw to screen you draw into a raster bitmap, while PDFs are mostly dynamic, like HTML. (unlike HTML they are more prone to be the same over different platforms, but that's beside the point)
If you really want to do that, the solution might be finding something that outputs PDFs, and then showing the generated PDF on screen at every step.
I guess that's the only way to have WYSIWYG results.

Categories