Fügen Sie mit PIL Text zum Bild hinzu

91

Ich habe eine Anwendung, die ein Bild lädt. Wenn der Benutzer darauf klickt, wird für dieses Bild ein Textbereich angezeigt (mit jquery), in dem der Benutzer Text auf das Bild schreiben kann. Welches sollte auf Bild hinzugefügt werden.

Nachdem ich einige Nachforschungen angestellt hatte, stellte ich fest, dass PIL(Python Imaging Library) mir dabei helfen kann. Also habe ich einige Beispiele ausprobiert, um zu sehen, wie es funktioniert, und es ist mir gelungen, Text auf ein Bild zu schreiben. Aber ich denke, es gibt einen Unterschied, wenn ich es mit Python Shellund in einer Webumgebung versuche . Ich meine, der Text auf dem Textbereich ist in px sehr groß. Wie kann ich mit PIL die gleiche Textgröße wie im Textbereich erreichen?

Der Text ist mehrzeilig. Wie kann ich es auch im Bild mehrzeilig machen PIL?

Gibt es einen besseren Weg als PIL? Ich bin mir nicht ganz sicher, ob dies die beste Implementierung ist.

html:

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

Es ist das Bild, das bearbeitet wird

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

die Abfrage zum Hinzufügen des Textbereichs. Auch der Textbereich ist Position: absolute und feste Größe.

Sollte ich es in ein Formular einfügen, damit ich die Koordinaten des Textbereichs auf dem Bild erhalten kann? Ich möchte Text auf ein Bild schreiben, wenn der Benutzer darauf klickt, und es auf dem Bild speichern.

Apostolos
quelle
Warum Sie mit PIL Text auf ein Bild schreiben möchten (und ich bin mir nicht sicher, ob PIL dabei hilft). Ist es nicht gut genug für Sie, Text in Overlay anzuzeigen, was am häufigsten in Schiebereglern verwendet wird?
Lalit
1
Ich brauche es für ein Projekt, bei dem das Bild gespeichert werden soll. Pil kann mit ImageDraw Text auf ein Bild zeichnen, weiß aber nicht, ob es einen anderen Weg gibt.
Apostolos
Es wird hilfreich sein, ob Sie den von Ihnen verwendeten Python-Code bereitstellen können?
Lalit
noch nicht in django implementiert. Ich habe versucht zu sehen, wie PIL in der interaktiven Python-Konsole funktioniert. Möchten Sie sehen, ob es zuerst funktioniert, und es dann in Django übertragen.
Apostolos
Was ist das $ -Symbol in Ihrem Code?
Mugen

Antworten:

170

Ich denke, das in verfügbare ImageFont- Modul PILsollte bei der Lösung des Problems der Textschriftgröße hilfreich sein. Überprüfen Sie einfach, welcher Schrifttyp und welche Schriftgröße für Sie geeignet sind, und verwenden Sie die folgende Funktion, um die Schriftwerte zu ändern.

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

Ihr Code sieht also ungefähr so ​​aus:

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

Möglicherweise müssen Sie zusätzliche Anstrengungen unternehmen, um die Schriftgröße zu berechnen. Falls Sie es basierend auf der Menge an Text ändern möchten, die der Benutzer eingegeben hat TextArea.

Um Textumbruch (mehrzeiliges Ding) hinzuzufügen, nehmen Sie einfach eine ungefähre Vorstellung davon, wie viele Zeichen in einer Zeile kommen können. Dann können Sie wahrscheinlich eine Vorverarbeitungsfunktion für Ihren Text schreiben, die im Grunde das Zeichen findet, das in jeder Zeile und in der Zeile das letzte ist konvertiert Leerzeichen vor diesem Zeichen in eine neue Zeile.

lalit
quelle
1
Das ist mein erster Gedanke. Müssen sich meine Schriftarten in einem bestimmten Ordner auf meinem Webserver befinden, damit sie funktionieren? Ich denke ja. Text umbrechen? Gibt es einen Standardweg oder muss ich einen implementieren?
Apostolos
Sie können die Schriftartdatei überall auf Ihrem Webserver aufbewahren. Stellen Sie einfach sicher, dass der von Ihnen angegebene Pfad korrekt ist.
Lalit
7
@lalit Ich habe Ihren Code auf einem Windows-Computer ausprobiert und eine Fehlermeldung für die Schriftart erhalten self.font = core.getfont(file, size, index, encoding) IOError: cannot open resource. Wie kann ich einen Pfad zur Schriftartdatei angeben?
LWZ
3
@LWZ, Um den obigen Code auszuführen, stellen Sie einfach sicher, dass sich die Schriftartdatei in dem aktuellen Verzeichnis befindet, in dem Sie den obigen Code ausführen. Wenn Sie es in Ihrem Programm verwenden, geben Sie einfach den vollständigen Pfad für Ihre Datei an, z. B. 'C: \ Windows \ Fonts \ sans-serif.ttf'. Eine andere Sache, die Sie hier sicherstellen müssen, ist, der Datei die entsprechenden Leseberechtigungen zu erteilen.
Lalit
3
font = ImageFont.truetype ("./ arial.ttf", 30); draw.textsize (msg, font = font);
WeizhongTu
16

Sie können ein Verzeichnis "fonts" in einem Stammverzeichnis Ihres Projekts erstellen und dort Ihre fonts-Datei (sans_serif.ttf) ablegen. Dann können Sie so etwas machen:

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)
svpp
quelle
14

Noch minimaleres Beispiel (zeichnet "Hallo Welt!" In Schwarz und mit der Standardschriftart oben links im Bild):

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

Zuerst müssen Sie einen Schrifttyp herunterladen ... zum Beispiel: https://www.wfonts.com/font/microsoft-sans-serif .

Verwenden Sie danach diesen Code, um den Text zu zeichnen:

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')
Kumar S.
quelle
4

Mit Pillow können Sie auch mit dem ImageDraw-Modul auf ein Bild zeichnen. Sie können Linien, Punkte, Ellipsen, Rechtecke, Bögen, Bitmaps, Akkorde, Pieslices, Polygone, Formen und Text zeichnen.

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

Wir erstellen ein Image-Objekt mit der new () -Methode. Dies gibt ein Bildobjekt ohne geladenes Bild zurück. Anschließend fügen wir dem Bild ein Rechteck und Text hinzu, bevor wir es speichern.

Tamil Selvan S.
quelle
3

Eine Sache, die in anderen Antworten nicht erwähnt wird, ist die Überprüfung der Textgröße. Es wird häufig benötigt, um sicherzustellen, dass der Text zum Bild passt (z. B. den Text kürzen, wenn er übergroß ist) oder um die Position zum Zeichnen des Textes zu bestimmen (z. B. ausgerichteter Text oben in der Mitte). Pillow / PIL bietet zwei Methoden zum Überprüfen der Textgröße: eine über ImageFont und eine über ImageDraw. Wie unten gezeigt, verarbeitet die Schriftart nicht mehrere Zeilen, während ImageDraw dies tut.

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)) 
lange
quelle
-7

Um einer Bilddatei Text hinzuzufügen, kopieren Sie einfach den folgenden Code und fügen Sie ihn ein

<?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>
Ramsevak Kumar
quelle