Pregunta

Usando Python quiero poder dibujar texto en diferentes ángulos usando PIL.

Por ejemplo, imagina que dibujas el número alrededor de la cara de un reloj. El número 3 aparecería como se esperaba, mientras que 12 dibujaríamos rotados en sentido antihorario 90 grados.

Por lo tanto, necesito poder dibujar muchas cadenas diferentes en muchos ángulos diferentes.

¿Fue útil?

Solución

Dibuje texto en una imagen en blanco temporal, gírelo y luego péguelo en la imagen original. Puede resumir los pasos en una función. Buena suerte descubriendo las coordenadas exactas a utilizar: mi cerebro empañado por el frío no está preparado ahora.

Esta demostración escribe texto amarillo en una inclinación sobre una imagen:

# Demo to add rotated text to an image using PIL

import Image
import ImageFont, ImageDraw, ImageOps

im=Image.open("stormy100.jpg")

f = ImageFont.load_default()
txt=Image.new('L', (500,50))
d = ImageDraw.Draw(txt)
d.text( (0, 0), "Someplace Near Boulder",  font=f, fill=255)
w=txt.rotate(17.5,  expand=1)

im.paste( ImageOps.colorize(w, (0,0,0), (255,255,84)), (242,60),  w)

Otros consejos

También es útil saber el tamaño de nuestro texto en píxeles antes de crear un objeto de imagen. Usé ese código al dibujar gráficos. Entonces no tuve problemas, p. con alineación de etiquetas de datos (la imagen es exactamente tan grande como el texto).

(...)
img_main = Image.new("RGB", (200, 200))
font = ImageFont.load_default()

# Text to be rotated...
rotate_text = u'This text should be rotated.'

# Image for text to be rotated
img_txt = Image.new('L', font.getsize(rotate_text))
draw_txt = ImageDraw.Draw(img_txt)
draw_txt.text((0,0), rotate_text, font=font, fill=255)
t = img_value_axis.rotate(90, expand=1)

El resto de unir las dos imágenes juntas ya se describe en esta página. Cuando gira por un " irregular " ángulo, tienes que mejorar este código un poco. Realmente funciona para 90, 180, 270 ...

No digo que esto vaya a ser fácil, o que esta solución sea necesariamente perfecta para ti, pero mira la documentación aquí:

http://effbot.org/imagingbook/pil-index.htm

y especialmente preste atención a los módulos Image, ImageDraw e ImageFont.

Aquí hay un ejemplo para ayudarlo:


import Image
im = Image.new("RGB", (100, 100))
import ImageDraw
draw = ImageDraw.Draw(im)
draw.text((50, 50), "hey")
im.rotate(45).show()

Para hacer lo que realmente desea, es posible que necesite hacer un montón de imágenes de texto rotadas correctamente y luego componerlas todas con una manipulación más sofisticada. Y después de todo eso todavía puede no verse bien. No estoy seguro de cómo se maneja el antialiasing y tal, por ejemplo, pero podría no ser bueno. Buena suerte, y si alguien tiene una manera más fácil, me interesaría saberlo también.

Aquí hay una versión funcional, inspirada en la respuesta, pero funciona sin abrir ni guardar imágenes.

Las dos imágenes tienen un fondo de color y un canal alfa diferente de cero para mostrar lo que está sucediendo. Cambiar los dos canales alfa de 92 a 0 los hará completamente transparentes.

from PIL import Image, ImageFont, ImageDraw

text = 'TEST'
font = ImageFont.truetype(r'C:\Windows\Fonts\Arial.ttf', 50)
width, height = font.getsize(text)

image1 = Image.new('RGBA', (200, 150), (0, 128, 0, 92))
draw1 = ImageDraw.Draw(image1)
draw1.text((0, 0), text=text, font=font, fill=(255, 128, 0))

image2 = Image.new('RGBA', (width, height), (0, 0, 128, 92))
draw2 = ImageDraw.Draw(image2)
draw2.text((0, 0), text=text, font=font, fill=(0, 255, 128))

image2 = image2.rotate(30, expand=1)

px, py = 10, 10
sx, sy = image2.size
image1.paste(image2, (px, py, px + sx, py + sy), image2)

image1.show()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top