Question

Utilisation de Python, je souhaite pouvoir dessiner du texte sous différents angles à l'aide de PIL.

Par exemple, imaginez que vous dessiniez le numéro autour d’une horloge. Le nombre 3 apparaîtra comme prévu, alors que 12 serait tourné à 90 degrés dans le sens anti-horaire.

Par conséquent, je dois être capable de dessiner de nombreuses chaînes différentes sous différents angles.

Était-ce utile?

La solution

Dessinez le texte dans une image vide temporaire, faites-le pivoter, puis collez-le sur l'image d'origine. Vous pouvez conclure les étapes d'une fonction. Bonne chance pour trouver les coordonnées exactes à utiliser - mon cerveau embué par le froid n'est pas à la hauteur pour le moment.

Cette démo écrit du texte jaune en oblique sur une image:

# 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)

Autres conseils

Il est également utile de connaître la taille de notre texte en pixels avant de créer un objet Image. J'ai utilisé ce code pour dessiner des graphiques. Ensuite, je n'ai pas de problèmes, par exemple avec alignement des étiquettes de données (l'image est exactement aussi grande que le texte).

(...)
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)

Le reste de la jonction des deux images est déjà décrit sur cette page. Lorsque vous effectuez une rotation avec un " irrégulier " angle, vous devez améliorer ce code un peu. Cela fonctionne réellement pour 90, 180, 270 ...

Je ne dis pas que cela va être facile, ni que cette solution sera forcément parfaite pour vous, mais regardez la documentation ici:

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

et surtout faites attention aux modules Image, ImageDraw et ImageFont.

Voici un exemple pour vous aider:


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

Pour faire ce que vous voulez vraiment, vous devrez peut-être créer plusieurs images de texte séparées correctement pivotées, puis les composer avec une manipulation plus sophistiquée. Et après tout, cela n’a toujours pas l’air génial. Je ne sais pas comment l'antialiasing, par exemple, est traité, mais ce n'est peut-être pas bon. Bonne chance, et si quelqu'un a un moyen plus facile, je serais également intéressé de le savoir.

Voici une version qui fonctionne, inspirée de la réponse, mais qui fonctionne sans ouvrir ni enregistrer les images.

Les deux images ont un fond coloré et un canal alpha différent de zéro pour montrer ce qui se passe. Changer les deux canaux alpha de 92 à 0 les rendra complètement transparents.

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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top