用于将文本创建为位图的工具(消除锯齿的文本,自定义间距,透明背景)

时间:2009-01-21 12:45:55

标签: python fonts bitmap spacing unix

我需要批量创建带文字的图片。要求:

  1. 任意大小的位图
  2. PNG格式
  3. 透明背景
  4. 黑色文字消除了对透明度的锯齿
  5. 可调节的字符间距
  6. 可调文本位置(文本开始的x和y坐标)
  7. TrueType和/或Type1支持
  8. Unix命令行工具或Python库
  9. 到目前为止,我已经评估了以下内容:

    PIL的问题在于Verdana的默认间距太稀疏了。我需要文本更紧凑,但是没有办法在PIL中调整它。

    在ImageMagick中,我还没有找到一种简单的方法来指定文本在图像中的位置(我使用-size WIDTHxHEIGHT和标题:'TEXT')。添加透明边框会使文本远离其所需的角落,但

    • 图像大小需要相应调整,因为边框会添加到范围
    • 无法独立调整水平和垂直偏移

    我是否错过了一些明显的替代方案或未能找到上述提到的必要功能?

3 个答案:

答案 0 :(得分:4)

(5)确实看起来很棘手,没有在字符串中插入虚拟窄空格(这将打破字距调整)或使用更高级别的东西,如SVG或HTML / CSS渲染器。

但是,如果你不介意弄脏手,那么很容易破解PIL的freetype渲染器添加水平空间。见_imagingft.c;在font_getsize和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;
}

添加:

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

首先尝试使用普通整数进行跟踪(可能通过'>> 6'判断相当大);编译并查看它是否有效。下一步是将跟踪值从Python中获取到C函数中,您必须将font_render中的ParseTuple调用更改为:

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

在font_getsize中:

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

然后看看你想要的Python界面。这是一个简单但相当繁琐的例子,通过界面的每个级别添加额外的“跟踪”参数,例如:

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

我还没有测试过这个!如果它有效,可能值得提交补丁。

答案 1 :(得分:3)

这是SVG + ImageMagick解决方案:

以编程方式创建基于此模板的SVG文档,将“TEXT HERE”替换为所需的文本内容:

<?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>

使用ImageMagick的convert将文档转换为背景透明的PNG:

$ convert -background none input.svg output.png

答案 2 :(得分:2)

快速浏览一下,Pango支持letter spacing。 Pango具有Python绑定并与Cairo集成。