Ferramentas para a criação de texto como bitmaps (texto anti-alias, espaçamento personalizado, fundo transparente)

StackOverflow https://stackoverflow.com/questions/465144

Pergunta

Eu preciso de lote criar imagens com texto. Requisitos:

  1. tamanho arbitrário de bitmap
  2. formato PNG
  3. fundo transparente
  4. texto preto anti-alias contra a transparência
  5. espaçamento entre caracteres ajustável
  6. posição texto ajustável (coordenadas x e y, onde começa o texto)
  7. TrueType e / ou apoio Type1
  8. ferramenta de linha de comando Unix ou biblioteca Python

Até agora eu avaliado o seguinte:

O problema com PIL é que, por exemplo, o espaçamento padrão para Verdana é muito escassa. Eu preciso o texto a ser um pouco mais apertado, mas não há nenhuma maneira de ajustá-lo no PIL.

Em ImageMagick eu não encontrei uma maneira fácil de especificar onde na imagem o texto começa (estou usando -size WIDTHxHEIGHT e legenda: 'TEXT'). Adicionando uma borda transparente irá mover o texto de distância da esquina é achored, mas

  • tamanho da imagem precisa ser ajustado em conformidade desde fronteira contribui para as extensões
  • não é possível ajustar deslocamento horizontal e vertical de forma independente

Eu perdi algumas alternativas óbvias ou não conseguiu encontrar recursos necessários a partir do acima mencionado?

Foi útil?

Solução 2

Aqui está a solução SVG + ImageMagick:

Criar programaticamente documentos SVG com base neste modelo, substituindo "texto aqui" com o conteúdo do texto desejado:

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

Converter os documentos para PNGs fundo transparente com convert do ImageMagick:

$ convert -background none input.svg output.png

Outras dicas

(5), na verdade parece complicado, curto de inserção de manequim estreitas-espaços na string (que vai quebrar kerning) ou usando algo muito mais elevado de nível como o SVG ou HTML / CSS renderizador.

No entanto, se você não se importa de sujar as mãos, parece bastante fácil de cortar renderizador freetype do PIL para adicionar espaço horizontal. Consulte _imagingft.c ; após o seguinte código em ambos os font_getsize e 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;
}

Adicionar:

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

Tente-o com um inteiro simples para rastreamento (provavelmente muito grande julgamento por esse '>> 6') em primeiro lugar; compilar e ver se funciona. O próximo passo seria a de obter o valor de rastreamento para a função C do Python, para o qual você teria que mudar a chamada ParseTuple em font_render a:

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

E em font_getsize:

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

Em seguida, olhar para o que Python interface que você deseja. Este é um caso trivial, mas muito tedioso de adicionar o extra 'tracking' argumento através de cada nível da interface, por exemplo:

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

Eu não testei nada disso! Se funcionar, pode valer a pena submeter como um patch.

A partir de um olhar rápido, Pango tem suporte para carta espaçamento . Pango tem vínculos Python e está integrado com o Cairo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top