2011-11-08 18 views

Respuesta

8

Usando cairo (con tanto código tomado de here):

import cairo 

def text_extent(font, font_size, text, *args, **kwargs): 
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0) 
    ctx = cairo.Context(surface) 
    ctx.select_font_face(font, *args, **kwargs) 
    ctx.set_font_size(font_size) 
    return ctx.text_extents(text) 

text='Example' 
font="Sans" 
font_size=55.0 
font_args=[cairo.FONT_SLANT_NORMAL] 
(x_bearing, y_bearing, text_width, text_height, 
x_advance, y_advance) = text_extent(font, font_size, text, *font_args) 
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(text_width), int(text_height)) 
ctx = cairo.Context(surface) 
ctx.select_font_face(font, *font_args) 
ctx.set_font_size(font_size) 
ctx.move_to(-x_bearing, -y_bearing) 
ctx.text_path(text) 
ctx.set_source_rgb(0.47, 0.47, 0.47) 
ctx.fill_preserve() 
ctx.set_source_rgb(1, 0, 0) 
ctx.set_line_width(1.5) 
ctx.stroke() 

surface.write_to_png("/tmp/out.png") 

enter image description here

+0

¿Necesito saber las dimensiones del texto para usar esto? –

+0

Puedo obtener la información necesaria con Context.text_extents ("Ejemplo") pero después de eso necesito crear una nueva superficie con el ancho y alto correctos. –

+0

Sí, desafortunadamente, no conozco una mejor manera. – unutbu

4

Usando imagemagick:

import subprocess 

args = { 
    'bgColor': 'transparent', 
    'fgColor': 'light slate grey', 
    'fgOutlineColor': 'red', 
    'text': 'Example', 
    'size': 72, 
    'geometry': '350x100!', 
    'output': '/tmp/out.png', 
    'font': 'helvetica' 
} 

cmd = ['convert', 'xc:{bgColor}', '-resize', '{geometry}', '-gravity', 'Center', 
     '-font', '{font}', '-pointsize', '{size}', '-fill', '{fgColor}', 
     '-stroke', '{fgOutlineColor}', '-draw', "text 0,0 '{text}'", '-trim', '{output}'] 
cmd = [item.format(**args) for item in cmd] 

proc = subprocess.Popen(cmd) 
proc.communicate() 

enter image description here

+0

bien lo hice no saber sobre .format (** args) –

+0

¿Necesito saber las dimensiones del texto de salida antes de poder crearlo? –

+0

Puedes usar cualquier 'geometría' que desees - imagemagick creará una imagen de exactamente esa geometría siempre que uses el signo de exclamación - pero si el tamaño de la fuente es demasiado grande, parte del texto puede recortarse . – unutbu

7

PIL no soporta esta pero se puede fingir: Rinda el texto cuatro u ocho veces con el color del contorno usando uno desplazamientos de píxeles:

x+1,y 
x-1,y 
x ,y+1 
x ,y-1 

(cuatro veces la versión)

x+1,y+1 
x ,y+1 
x-1,y+1 

x+1,y 
x-1,y 

x+1,y-1 
x ,y-1 
x-1,y-1 

(ocho veces versión)

y luego una vez en x,y con el color de relleno.

+1

La versión 8x es básicamente equivalente a renderizar 4 veces solo en las diagonales. –

+0

¿No es esto un golpe de rendimiento empinado? –

+0

@HassanBaig No lo notarás. –

1

Usted puede utilizar Inkscape:

import subprocess 
subprocess.call("inkscape in.svg --export-text-to-path --export-plain-svg out.svg", shell = True) 

nota: usted tiene que descargar Inkscape a usar esto, por lo que no es práctico para el uso permanente

Cuestiones relacionadas