Aggiungi testo sull'immagine utilizzando PIL


93

Ho un'applicazione che carica un'immagine e quando l'utente fa clic su di essa, viene visualizzata un'area di testo per questa immagine (utilizzando jquery), dove l'utente può scrivere del testo sull'immagine. Che dovrebbe essere aggiunto su Image.

Dopo aver fatto alcune ricerche su di esso, ho pensato che PIL(Python Imaging Library) potesse aiutarmi a farlo. Quindi ho provato un paio di esempi per vedere come funziona e sono riuscito a scrivere del testo su un'immagine. Ma penso che ci sia qualche differenza quando lo provo usando Python Shelle in ambiente web. Voglio dire che il testo nell'area di testo è molto grande in px. Come posso ottenere la stessa dimensione di testo quando utilizzo PIL di quella nell'area di testo?

Il testo è multilinea. Come posso renderlo multilinea anche nell'immagine, usando PIL?

C'è un modo migliore rispetto all'utilizzo di PIL? Non sono del tutto sicuro, se questa è la migliore implementazione.

html:

<img src="images/test.jpg"/>

è l'immagine che viene modificata

var count = 0;
$('textarea').autogrow();
$('img').click(function(){
    count = count + 1;
    if (count > 1){
        $(this).after('<textarea />');
        $('textarea').focus();
    }   
});

il jquery per aggiungere la textarea. Anche l'area di testo è la posizione: dimensione assoluta e fissa.

Devo posizionarlo all'interno di un modulo in modo da poter ottenere le coordinate della textarea sull'immagine? Voglio scrivere del testo sull'immagine quando l'utente fa clic e salvarlo sull'immagine.


Perché vuoi scrivere del testo su un'immagine usando PIL (e non sono sicuro se PIL aiuta in questo). Non è abbastanza buono per mostrare il testo in sovrapposizione, che viene utilizzato più comunemente nei cursori.
lalit

1
Ne ho bisogno per un progetto e voglio che l'immagine venga salvata. Pil può disegnare del testo su un'immagine usando ImageDraw, non so se c'è un altro modo.
Apostolos

Sarà utile, se puoi fornire il codice Python che stai usando?
lalit

non ancora implementato in django. Ho provato a vedere come funziona PIL nella console interattiva di Python. Vuoi vedere prima se funziona e poi trasferirlo in Django.
Apostolos

Qual è il simbolo $ nel tuo codice?
Mugen

Risposte:


171

Penso che il modulo ImageFont disponibile in PILdovrebbe essere utile per risolvere il problema della dimensione del carattere del testo. Basta controllare il tipo e la dimensione del carattere appropriato per te e utilizzare la seguente funzione per modificare i valori del carattere.

# font = ImageFont.truetype(<font-file>, <font-size>)
# font-file should be present in provided path.
font = ImageFont.truetype("sans-serif.ttf", 16)

Quindi il tuo codice avrà un aspetto simile a:

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 

img = Image.open("sample_in.jpg")
draw = ImageDraw.Draw(img)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype("sans-serif.ttf", 16)
# draw.text((x, y),"Sample Text",(r,g,b))
draw.text((0, 0),"Sample Text",(255,255,255),font=font)
img.save('sample-out.jpg')

Potrebbe essere necessario fare uno sforzo in più per calcolare la dimensione del carattere. Nel caso in cui desideri modificarlo in base alla quantità di testo fornito dall'utente TextArea.

Per aggiungere il wrapping del testo (cosa multilinea) prendi solo un'idea approssimativa di quanti caratteri possono venire in una riga, quindi puoi probabilmente scrivere una funzione di pre-elaborazione per il tuo testo, che fondamentalmente trova il carattere che sarà l'ultimo in ogni riga e converte lo spazio bianco prima di questo carattere in una nuova riga.


1
Questo è il mio pensiero iniziale. Quindi ho bisogno che i miei caratteri si trovino in una cartella specifica nel mio server web per funzionare? Avvolgere il testo? Esiste un modo standard o devo implementarne uno?
Apostolos

Puoi mantenere il file del carattere ovunque nel tuo server web. Assicurati solo che il percorso fornito sia corretto.
lalit

7
@lalit Ho provato il tuo codice su una macchina Windows e ho ricevuto un errore per il carattere self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource. Come posso fornire il percorso al file del carattere?
LWZ

3
@LWZ, per eseguire il codice sopra, assicurati che il file del carattere si trovi nella directory corrente in cui stai eseguendo il codice sopra. Nel caso in cui lo utilizzi nel tuo programma, specifica semplicemente il percorso completo del tuo file, ad esempio "C: \ Windows \ Fonts \ sans-serif.ttf". Un'altra cosa che devi assicurarti qui è dare le autorizzazioni di lettura appropriate al file.
lalit

3
font = ImageFont.truetype ("./ arial.ttf", 30); draw.textsize (msg, font = font);
WeizhongTu

16

Puoi creare una directory "fonts" in una radice del tuo progetto e inserire il tuo file fonts (sans_serif.ttf) lì. Quindi puoi creare qualcosa del genere:

fonts_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fonts')
font = ImageFont.truetype(os.path.join(fonts_path, 'sans_serif.ttf'), 24)

15

Esempio ancora più minimale (disegna "Hello world!" In nero e con il carattere predefinito in alto a sinistra dell'immagine):

...
from PIL import ImageDraw
...
ImageDraw.Draw(
    image  # Image
).text(
    (0, 0),  # Coordinates
    'Hello world!',  # Text
    (0, 0, 0)  # Color
)

6

Per prima cosa, devi scaricare un tipo di carattere ... ad esempio: https://www.wfonts.com/font/microsoft-sans-serif .

Dopodiché, usa questo codice per disegnare il testo:

from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 
img = Image.open("filename.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(r'filepath\..\sans-serif.ttf', 16)
draw.text((0, 0),"Draw This Text",(0,0,0),font=font) # this will draw text with Blackcolor and 16 size

img.save('sample-out.jpg')

4

Con Pillow, puoi anche disegnare su un'immagine usando il modulo ImageDraw. Puoi disegnare linee, punti, ellissi, rettangoli, archi, bitmap, accordi, fette di torta, poligoni, forme e testo.

from PIL import Image, ImageDraw
blank_image = Image.new('RGBA', (400, 300), 'white')
img_draw = ImageDraw.Draw(blank_image)
img_draw.rectangle((70, 50, 270, 200), outline='red', fill='blue')
img_draw.text((70, 250), 'Hello World', fill='green')
blank_image.save('drawn_image.jpg')

creiamo un oggetto Image con il metodo new (). Ciò restituisce un oggetto Image senza immagine caricata. Quindi aggiungiamo un rettangolo e del testo all'immagine prima di salvarla.


3

Una cosa non menzionata in altre risposte è controllare la dimensione del testo. Spesso è necessario per assicurarsi che il testo si adatti all'immagine (es. Accorciare il testo se sovradimensionato) o per determinare la posizione in cui disegnare il testo (es. Testo allineato in alto al centro). Pillow / PIL offre due metodi per controllare la dimensione del testo, uno tramite ImageFont e uno tramite ImageDraw. Come mostrato di seguito, il carattere non gestisce più righe, mentre ImageDraw lo fa.

In [28]: im = Image.new(mode='RGB',size=(240,240))                                                            
In [29]: font = ImageFont.truetype('arial')
In [30]: draw = ImageDraw.Draw(im)
In [31]: t1 = 'hello world!'
In [32]: t2 = 'hello \nworld!'
In [33]: font.getsize(t1), font.getsize(t2) # the height is the same
Out[33]: ((52, 10), (60, 10)) 
In [35]: draw.textsize(t1, font), draw.textsize(t2, font)  # handles multi-lined text
Out[35]: ((52, 10), (27, 24)) 

-8

Per aggiungere testo a un file immagine, copia / incolla il codice sottostante

<?php
$source = "images/cer.jpg";
$image = imagecreatefromjpeg($source);
$output = "images/certificate".rand(1,200).".jpg";
$white = imagecolorallocate($image,255,255,255);
$black = imagecolorallocate($image,7,94,94);
$font_size = 30;
$rotation = 0;
$origin_x = 250;
$origin_y = 450;
$font = __DIR__ ."/font/Roboto-Italic.ttf";
$text = "Dummy";
$text1 = imagettftext($image,$font_size,$rotation,$origin_x,$origin_y,$black,$font,$text);
     imagejpeg($image,$output,99);
?> <img src="<?php echo $output; ?>"> <a href="<?php echo $output;    ?>" download="<?php echo $output; ?>">Download Certificate</a>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.