2011-11-24 32 views
11

Estoy usando PIL para dibujar texto en una imagen. ¿Cómo puedo envolver una cadena de texto? Este es mi código:Ajustar texto en PIL

text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." 

image = Image.open("/tmp/background-image.jpg") 
draw = ImageDraw.Draw(image) 
font = ImageFont.truetype("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"), 50, encoding='unic') 
draw.text((100, 100), text, font=font, fill="#aa0000") 
image.save("/tmp/image.jpg") 

Respuesta

10

Primero tendrá que dividir el texto en líneas de la longitud correcta, y luego dibujar cada línea individualmente.

La segunda parte es fácil, pero la primera parte puede ser bastante difícil de hacer con precisión si se usan fuentes de ancho variable. Si de ancho fijo se utilizan tipos de letra, o si la precisión no importa mucho, a continuación, sólo pueden utilizar el módulo de textwrap para dividir el texto en líneas de un ancho determinado carácter:

margin = offset = 40 
for line in textwrap.wrap(text, width=40): 
    draw.text((margin, offset), line, font=font, fill="#aa0000") 
    offset += font.getsize(line)[1] 
+0

Esta es la división por número de caracteres, no anchura real - es decir, para encajar en una imagen – User

3

Bueno, puede hacerlo de forma manual, por supuesto, con el \ n cada vez que desea ajustar el texto. No es la mejor manera si tiene diferentes cadenas cada vez pero le da control total sobre el resultado. Pero también está el módulo de envoltura de texto. Puede usarlo de esta manera:

import textwrap 
texto = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." 
novo = textwrap.wrap(texto, width=20) 
print(novo) 

Resultados:

>>> 
['Lorem ipsum dolor', 'sit amet,', 'consectetur', 'adipisicing elit,', 'sed do eiusmod', 'tempor incididunt ut', 'labore et dolore', 'magna aliqua. Ut', 'enim ad minim', 'veniam, quis nostrud', 'exercitation ullamco', 'laboris nisi ut', 'aliquip ex ea', 'commodo consequat.', 'Duis aute irure', 'dolor in', 'reprehenderit in', 'voluptate velit esse', 'cillum dolore eu', 'fugiat nulla', 'pariatur. Excepteur', 'sint occaecat', 'cupidatat non', 'proident, sunt in', 'culpa qui officia', 'deserunt mollit anim', 'id est laborum.'] 

devuelve una lista de términos en la cadena anterior envuelta de acuerdo con el ancho que determinado.

0

El texto aceptado envolturas basándose en el límite fijo de 40 caracteres por línea, sin tener en cuenta el ancho de la caja (en píxeles) o el tamaño de la fuente. Esto puede conducir fácilmente a un llenado insuficiente o excesivo.

Aquí es una solución mejor - un simple fragmento de código para manejar ajuste de texto utilizando fuente basado en medida de ancho: https://gist.github.com/turicas/1455973

Cuestiones relacionadas