2009-12-27 9 views
5

Ich verwende die folgenden zwei Methoden, um Text Vorschaubild für eine Ttf SchriftdateiImageFont's getsize() bekommt nicht die korrekte Textgröße?

PIL Verfahren zu generieren:

def make_preview(text, fontfile, imagefile, fontsize=30): 
    try: 
     font = ImageFont.truetype(fontfile, fontsize) 
     text_width, text_height = font.getsize(text) 
     img = Image.new('RGBA', (text_width, text_height)) 
     draw = ImageDraw.Draw(img) 
     draw.text((0, 0), text, font=font, fill=(0, 0, 0)) 
     return True 
    except: 
     return False 

ImageMagick Methode:

def make_preview(text, fontfile, imagefile, fontsize=30): 
    p = subprocess.Popen(['convert', '-font', fontfile, '-background', 
      'transparent', '-gravity', 'center', '-pointsize', str(fontsize), 
      '-trim', '+repage', 'label:%s' % text, image_file]) 
    return p==0 

Beide Methoden Erstellen Sie in den meisten Fällen korrekte Vorschaubilder, aber in einigen seltenen Fällen (< 2%), die font.getsize (Text) nur cann ot erhalten die richtige Textgröße, die zu einem übergelaufenen bereitgestellten Canvas führt. ImageMagick hat dasselbe Problem.

Beispiel Fonts und Previews:

HANFORD.TTF http://download.appfile.com/HANFORD.png

NEWTOW.TTF http://download.appfile.com/NEWTOW.png

MILF.TTF http://download.appfile.com/MILF.png

Ich habe in ImageMagicks Dokumentationen geschaut und fand die Erklärung dieses Problems bei http://www.imagemagick.org/Usage/text/#overflow.

Ist es möglich, solche Textüberläufe zu erkennen und Text so zu zeichnen, wie wir es erwartet haben?

Antwort

1

In diesem Fall geben Sie einfach ImageMagick an, um eine größere Leinwandgröße mit einer festen Schriftgröße zu verwenden, und es wird Text in der angegebenen Punktgröße gezeichnet, während seine Integrität beibehalten wird.

def make_preview(text, fontfile, imagefile, fontsize=30): 
    p = subprocess.call(['convert', '-font', fontfile, '-background', 
     'transparent', '-gravity', 'center', '-size', '1500x300', 
     '-pointsize', str(fontsize), '-trim', '+repage', 'label:%s' % text, image_file]) 
    return p==0 

Wenn Sie einen Text angegeben Leinwand passen müssen, anstatt eine feste Punktgröße verwenden, müssen Sie möglicherweise das Ausgangsbild, um die Größe, nachdem es erstellt wird.

PIL macht das nicht sehr gut, exotische Schriftarten zeichnen, egal, welche Punktgröße Sie angeben, um eine Schriftart zu laden, es überläuft Text immer außerhalb des Ausgabebildes.

2

Ich hatte ein ähnliches Problem einmal in PHP und ImageMagick.

Am Ende löste ich dies, indem ich den Text auf einer sehr großen Leinwand zeichnete, und dann trimmte es mit den trim/auto-crop Funktionen, die zusätzlichen Platz aus dem Bild rasieren.

Wenn ich Ihre Vorschau-Funktion richtig verstehe, tut es tatsächlich schon genau das: Es sollte ausreichen, nur die Breite und Höhe Einstellungen zu entfernen.

+0

@Pekka, Ihre Methode funktioniert möglicherweise mit IM, aber es wird große Overhead erstellen, nicht nur Zuschneiden, sondern auch Größe angepasstes Bild anpassen, um in die angegebene Leinwand Dimension zu passen. Dies funktioniert nicht mit PIL. Es zeichnet immer obere Hälfte der oben genannten Schriftarten, auch wenn ich eine größere Leinwand erstelle. – jack

+0

Versuchen Sie, den Befehl "label" vor den Befehlen trim und repage zu setzen, die funktionieren sollten. Der Overhead, ich kann nicht helfen. –

5

alt text http://img9.imageshack.us/img9/2419/fontfix.jpg

kein Programmierlösung, aber wenn ich Ihr Problem zu regenerieren, geschieht es ist nur auf Ihre Schriften (andere Schriftarten wie Arial alles kein Problem ist), so habe ich Ihre Schriftart-Dateien festgelegt (durch Aufstieg Ändern/anständige Metriken).Sie können herunterladen here,

Und tut mir leid über Hanford Script Font, es ist nicht perfekt, wie Sie sehen, Höhe scheint in Ordnung, aber die linke Seite ist nicht gezeichnet, es ist aus meinem Verständnis heraus.

UPDATE: In Bezug auf Hanford Font, ist hier eine Arbeit um, passiert zusätzlichen Platz in Text wie "Handford Script" und dann den zusätzlichen Platz in Bild zuschneiden wie img=img.crop(img.getbbox())

alt text http://img64.imageshack.us/img64/1903/hanfordfontworkaround.jpg

UPDATE2: ich hatte Farbe pass = (255,255,255) in Image.New auf weißen Hintergrund Schwarz-Text zu bekommen

img = Image.new('RGBA', (text_width, text_height),color=(255,255,255)) 

+0

Wie ändert man die Aufstieg/Angemessenen Metrik für eine bestimmte Schriftart? Ist eine manuelle Neuberechnung pro Schriftart erforderlich? – jack

+0

Ich benutzte fontforge, um diese Schriftarten zu bearbeiten, jack. – YOU

+0

Aufgrund von Urheberrechtsproblemen, denke ich, ist es besser, die Schriftart so zu belassen wie sie ist und Text auf einer größeren Leinwand zu zeichnen und sie dann zu beschneiden. aber deine Methode hat für den persönlichen Gebrauch funktioniert. Danke für deinen Rat. – jack