Domanda

Usando Python voglio essere in grado di disegnare testo con diverse angolazioni usando PIL.

Ad esempio, immagina di disegnare il numero attorno al quadrante di un orologio. Il numero 3 sembrerebbe come previsto mentre 12 avremmo disegnato ruotato di 90 gradi in senso antiorario.

Pertanto, devo essere in grado di disegnare molte stringhe diverse con angolazioni diverse.

È stato utile?

Soluzione

Disegna il testo in un'immagine temporanea vuota, ruotala, quindi incollala sull'immagine originale. Potresti concludere i passaggi in una funzione. Buona fortuna a capire le coordinate esatte da usare - il mio cervello annebbiato dal freddo non è all'altezza in questo momento.

Questa demo scrive un testo giallo su una pendenza sopra un'immagine:

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

Altri suggerimenti

È anche utile conoscere le dimensioni del nostro testo in pixel prima di creare un oggetto Image. Ho usato un tale codice per disegnare grafici. Quindi non ho avuto problemi ad es. con allineamento delle etichette dei dati (l'immagine è esattamente grande quanto il testo).

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

Il resto dell'unione delle due immagini è già descritto in questa pagina. Quando ruoti di un "non regolare" angolo, devi migliorare un po 'questo codice. In realtà funziona per 90, 180, 270 ...

Non sto dicendo che sarà facile, o che questa soluzione sarà necessariamente perfetta per te, ma guarda la documentazione qui:

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

e in particolare prestare attenzione ai moduli Image, ImageDraw e ImageFont.

Ecco un esempio per aiutarti:


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

Per fare ciò che desideri davvero, potresti aver bisogno di creare un gruppo di immagini di testo separate correttamente ruotate e poi comporle tutte insieme con qualche manipolazione più elaborata. E dopotutto potrebbe non sembrare eccezionale. Non sono sicuro di come sia gestito l'antialiasing e simili, ma potrebbe non essere buono. Buona fortuna, e se qualcuno ha un modo più semplice, sarei anche interessato a saperlo.

Ecco una versione funzionante, ispirata alla risposta, ma funziona senza aprire o salvare le immagini.

Le due immagini hanno uno sfondo colorato e un canale alfa diversi da zero per mostrare cosa sta succedendo. La modifica dei due canali alfa da 92 a 0 li renderà completamente trasparenti.

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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top