Ferramentas para a criação de texto como bitmaps (texto anti-alias, espaçamento personalizado, fundo transparente)
Pergunta
Eu preciso de lote criar imagens com texto. Requisitos:
- tamanho arbitrário de bitmap
- formato PNG
- fundo transparente
- texto preto anti-alias contra a transparência
- espaçamento entre caracteres ajustável
- posição texto ajustável (coordenadas x e y, onde começa o texto)
- TrueType e / ou apoio Type1
- ferramenta de linha de comando Unix ou biblioteca Python
Até agora eu avaliado o seguinte:
- Python Imaging Library :. Falhar 5
- ImageMagick (opção "caput"):. Difícil descobrir 6
- pycairo :. Falhar 5
- SVG + ImageMagick convertido : mais promissor, embora requer várias ferramentas
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?
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.