Tools for creating text in the form of bitmap images (smooth text, custom spacing, transparent background)

I need batch image creation with text. Requirements:

  • custom bitmap size
  • PNG format
  • transparent background
  • black text anti-aliasing
  • adjustable character spacing
  • customizable text position (x and y coordinates where the text starts)
  • TrueType and / or Type1 support
  • Unix command line tool or Python library

So far I have appreciated the following:

The problem with PIL is that, for example, the default interval for Verdana is too rare. I need the text to be a little denser, but there is no way to set it in PIL.

In ImageMagick, I did not find an easy way to indicate where the text begins in the picture (I use -WID size, thanks HEIGHT and caption: TEXT). Adding a transparent border will move the text away from the corner to which it is attached, but

  • image size needs to be adjusted accordingly as the border adds extents
  • it is impossible to adjust horizontal and vertical displacement independently

Am I missing some obvious alternatives or could not find the necessary functions from the above?

+4
source share
3 answers

Here's the SVG + ImageMagick solution:

Programmatically create SVG documents based on this template, replacing "TEXT HERE" with the desired text content:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg version="1.0" width="152px" height="50px"> <text style="font-size: 22px; font-weight:bold; font-family: Verdana-Bold; letter-spacing: -1.3%;"> <tspan x="10" y="39">TEXT HERE</tspan> </text> </svg> 

Convert documents to transparent PNG using ImageMagick convert :

 $ convert -background none input.svg output.png 
+3
source

(5) it really looks complicated without inserting fictitious narrow spaces into the line (which will cause kerning to break) or using something of a much higher level, such as SVG or HTML / CSS rendering.

However, if you don't mind keeping your hands dirty, it's pretty easy to hack a PIL rendering renderer to add horizontal space. See _imagingft.c ; after the following code in font_getsize and font_render:

 if (kerning && last_index && index) { FT_Vector delta; FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, &delta); x += delta.x >> 6; } 

Add

 if (last_index && index) { x += tracking; } 

Try this with a simple integer to track (probably large enough, judging by the fact that “→ 6”); compile and see if it works. The next step would be to get the tracking value in the C function from Python, for which you would have to change the ParseTuple call in font_render to:

 long tracking; if (!PyArg_ParseTuple(args, "Ol|il:render", &string, &id, &mask, &tracking)) return NULL; 

And in font_getsize:

 long tracking; if (!PyArg_ParseTuple(args, "O|l:getsize", &string, &tracking)) return NULL; 

Then see which Python interface you want. This is a trivial but rather tedious case of adding an additional tracking argument through each level of the interface, for example:

 def truetype(filename, size, index=0, encoding="", tracking= 0): # added optional tracking "Load a truetype font file." try: return FreeTypeFont(filename, size, index, encoding, tracking) # added tracking ... class FreeTypeFont: "FreeType font wrapper (requires _imagingft service)" def __init__(self, file, size, index=0, encoding="", tracking= 0): # added tracking import _imagingft self.font = _imagingft.getfont(file, size, index, encoding) self.tracking= tracking # add this line ... def getmask2(self, text, mode="", fill=Image.core.fill): size, offset = self.font.getsize(text, self.tracking) # use tracking im = fill("L", size, 0) self.font.render(text, im.id, mode=="1", self.tracking) # use tracking return im, offset 

I have not tested anything! If this works, it might be worth sending a patch.

+4
source

With a quick glance, Pango maintains the spacing between letters . Pango has Python bindings and is integrated with Cairo.

+2
source

All Articles