2009-12-28 15 views

risposta

61

Utilizzare Draw.textsize method per calcolare la dimensione del testo e ricalcolare la posizione di conseguenza.

Ecco un esempio:

from PIL import Image, ImageDraw 

W, H = (300,200) 
msg = "hello" 

im = Image.new("RGBA",(W,H),"yellow") 
draw = ImageDraw.Draw(im) 
w, h = draw.textsize(msg) 
draw.text(((W-w)/2,(H-h)/2), msg, fill="black") 

im.save("hello.png", "PNG") 

e il risultato:

image with centered text

+5

draw.textsize: (self, text, font = None) – WeizhongTu

+4

Se la dimensione del carattere è diversa, è importante includere il carattere in questo modo: 'draw.textsize (msg, font = myFont)', altrimenti ha vinto 't ottenere centrato correttamente – Coco

2

Utilizzare il metodo textsize (vedere docs) per calcolare le dimensioni dell'oggetto di testo prima di disegnarlo effettivamente. Quindi disegnalo partendo dalle coordinate appropriate.

42

Ecco alcuni esempi di codice che utilizza textwrap dividere una linea lunga in pezzi, e quindi utilizza il textsize metodo per calcolare le posizioni.

from PIL import Image, ImageDraw, ImageFont 
import textwrap 

astr = '''The rain in Spain falls mainly on the plains.''' 
para = textwrap.wrap(astr, width=15) 

MAX_W, MAX_H = 200, 200 
im = Image.new('RGB', (MAX_W, MAX_H), (0, 0, 0, 0)) 
draw = ImageDraw.Draw(im) 
font = ImageFont.truetype(
    '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf', 18) 

current_h, pad = 50, 10 
for line in para: 
    w, h = draw.textsize(line, font=font) 
    draw.text(((MAX_W - w)/2, current_h), line, font=font) 
    current_h += h + pad 

im.save('test.png') 

enter image description here

+0

+1 per esempio di utilizzo di parametro font opzionale – btk

3

Si potrebbe trovare un'implementazione di questo a http://tools.jedutils.com/tools/center-text-image

Si potrebbe utilizzare la pagina per creare l'immagine proprio lì, invece di attuare la routine di te stesso, ma il codice utilizzato è incluso nel pagina anche.

9

Si noti che il metodo Draw.textsize non è accurato. Stavo lavorando con immagini a basso pixel, e dopo alcuni test, si è scoperto che textize considera ogni personaggio di 6 pixel di larghezza, mentre un "I" occupa il massimo. 2 pixel e una "W" richiede min. 8 pixel (nel mio caso). E così, a seconda del mio testo, era o non era affatto centrato. Comunque, credo che "6" fosse una media, quindi se lavori con testi lunghi e immagini grandi, dovrebbe essere ancora ok.

Ma ora, se volete un po precisione reale, è meglio utilizzare il metodo getsize dell'oggetto tipo di carattere che si vuole utilizzare:

arial = ImageFont.truetype("arial.ttf", 9) 
w,h = arial.getsize(msg) 
draw.text(((W-w)/2,(H-h)/2), msg, font=arial, fill="black") 

Come utilizzato nel collegamento di Edilio.

+0

Non la risposta alla domanda dell'OP, ma bella funzione urgentemente necessaria. 1+ – ddlab

+0

Avviso importante: questa funzione 'getsize' accetta caratteri non latini come Umlauts in euro o tedesco. 'textsize' no. Pollice su :-) – ddlab

Problemi correlati