8 Stimmen

Schreiben von Text mit diakritischen Zeichen ("nikud", Vokalisationszeichen) mit PIL (Python Imaging Library)

Das Schreiben von einfachem Text auf einem Bild mit PIL ist einfach.

draw = ImageDraw.Draw(img)
draw.text((10, y), text2, font=font, fill=forecolor )

Wenn ich jedoch versuche, hebräische Satzzeichen (genannt "nikud" oder ) zu schreiben, überschneiden sich die Zeichen nicht so, wie sie sollten. (Ich nehme an, dass diese Frage auch für Arabisch und andere ähnliche Sprachen gilt).

In einer unterstützenden Umgebung nehmen diese beiden Wörter denselben Platz bzw. dieselbe Breite ein (das folgende Beispiel hängt von Ihrem System ab, daher die Abbildung):

Wenn ich jedoch den Text mit PIL zeichne, erhalte ich:

da die Bibliothek wahrscheinlich die Kerning(?)-Regeln nicht beachtet.

Ist es möglich, dass das Zeichen und das hebräische Satzzeichen denselben Platz bzw. dieselbe Breite einnehmen, ohne dass die Zeichenpositionierung manuell eingegeben werden muss?

bild - nikud und buchstabenabstände http://tinypic.com/r/jglhc5/5

Bild-Url: http://tinypic.com/r/jglhc5/5

9voto

Nasser Al-Wohaibi Punkte 4369

In Bezug auf Arabisch diakritische Zeichen : Python + Zauberstab (Python Lib) +arabic_reshaper(Python Lib) +bidi.algorithme(Python Lib). Das Gleiche gilt für PIL/Kissen verwenden, müssen Sie die arabic_reshaper y bidi.algorithm und übergeben Sie den erzeugten Text an draw.text((10, 25), artext, font=font) :

from wand.image import Image as wImage
from wand.display import display as wdiplay
from wand.drawing import Drawing
from wand.color import Color
import arabic_reshaper
from bidi.algorithm import get_display

reshaped_text = arabic_reshaper.reshape(u' ')
artext = get_display(reshaped_text)

fonts = ['C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\DroidNaskh-Bold.ttf',
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit.ttf',
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Bold-Oblique.ttf',
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Bold.ttf',
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\Thabit-Oblique.ttf',
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\majalla.ttf',         
         'C:\\Users\\PATH\\TO\\FONT\\Thabit-0.02\\majallab.ttf',

         ]
draw = Drawing()
img =  wImage(width=1200,height=(len(fonts)+2)*60,background=Color('#ffffff')) 
#draw.fill_color(Color('#000000'))
draw.text_alignment = 'right';
draw.text_antialias = True
draw.text_encoding = 'utf-8'
#draw.text_interline_spacing = 1
#draw.text_interword_spacing = 15.0
draw.text_kerning = 0.0
for i in range(len(fonts)):
    font =  fonts[i]
    draw.font = font
    draw.font_size = 40
    draw.text(img.width / 2, 40+(i*60),artext)
    print draw.get_font_metrics(img,artext)
    draw(img)
draw.text(img.width / 2, 40+((i+1)*60),u' test')
draw(img)
img.save(filename='C:\\PATH\\OUTPUT\\arabictest.png'.format(r))
wdiplay(img)

Arabic typography in images

5voto

Berry Tsakala Punkte 13033

Lustigerweise habe ich nach 5 Jahren und mit großer Hilfe von @Nasser Al-Wohaibi herausgefunden, wie man das macht:

Die Umkehrung des Textes mit einem BIDI-Algorithmus war erforderlich.

# -*- coding: utf-8 -*-
from bidi.algorithm import get_display
import PIL.Image, PIL.ImageFont, PIL.ImageDraw
img= PIL.Image.new("L", (400, 200))
draw = PIL.ImageDraw.Draw(img)
font = PIL.ImageFont.truetype( r"c:\windows\fonts\arial.ttf", 30)
t1 = u' !'
draw.text( (10,10), 'before BiDi :' + t1, fill=255, font=font)

t2 = get_display(t1)        # <--- here's the magic <---
draw.text( (10,50), 'after BiDi: ' + t2, fill=220, font=font)

img.save( 'bidi-test.png')

Die Antwort von @Nasser hat einen zusätzlichen Wert, der wahrscheinlich nur für arabische Texte relevant ist (die Buchstaben im Arabischen ändern ihre Form und ihren Zusammenhang auf der Grundlage ihrer Nachbarbuchstaben, im Hebräischen sind alle Buchstaben getrennt), daher war nur der Bidi-Teil für diese Frage relevant.

im Ergebnis der Probe, die 2. Zeile ist die korrekte Form, und die korrekte Vokalisierung markiert die Positionierung.

before and after bidi

Vielen Dank an @tzot für die Hilfe und die Codeschnipsel

a-propos:

Beispiele für das unterschiedliche Verhalten von Schriftarten bei der hebräischen "nikud". Nicht alle Schriftarten verhalten sich gleich: sample PIL written, bidi hebrew text, with nikud, in different fonts

0 Stimmen

Hallo, ich habe eine ähnliches Problem mit Pillow . Haben Sie jemals eine Lösung gefunden, um das nikud unabhängig von der Schriftart richtig auszurichten?

2voto

tzot Punkte 86792

An welchem System arbeiten Sie? Bei mir funktioniert es auf meinem Gentoo-System; die Reihenfolge der Buchstaben ist umgekehrt (ich habe einfach von Ihrer Frage kopiert), was mir korrekt erscheint, obwohl ich nicht viel über RTL-Sprachen weiß.

Python 2.5.4 (r254:67916, May 31 2009, 16:56:01)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Image as I, ImageFont as IF, ImageDraw as ID
>>> t= u" "
>>> t
u'\u05e1\u05b6\u05e4\u05b6\u05e8 \u05e1\u05e4\u05e8'
>>> i= I.new("L", (200, 200))
>>> d= ID.Draw(i)
>>> f= IF.truetype("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20)
>>> d1.text( (100, 40), t, fill=255, font=f)
>>> i.save("/tmp/dummy.png", optimize=1)

produziert:

the example text rendered as white on black

EDIT: Ich sollte sagen, dass die Verwendung des Deja Vu Sans war kein Zufall; obwohl ich sie nicht besonders mag (und ich finde ihre Glyphen besser als die von Arial), ist sie lesbar, hat eine erweiterte Unicode-Abdeckung und scheint mit vielen Nicht-MS-Anwendungen besser zu funktionieren als Arial Unicode MS .

0 Stimmen

Sie haben nicht wirklich geantwortet, aber Sie helfen, den Fehler zu sehen: Nur DejaVuSans.ttf und Lucidaxxx.ttf verhalten sich unter PIL korrekt! Alle anderen meiner TTF-Dateien produzierten eine falsche Ausgabe (aber sie verhalten sich außerhalb von PIL gut). Sie können andere Schriftarten ausprobieren, z.B. Arial.ttf

1 Stimmen

Eine TrueType-Schriftart (oder OpenType-Schriftart) bedeutet nicht unbedingt, dass es sich um eine vollständige und in allen Anwendungen nützliche Schrift handelt. Michael Kaplan (der derzeit für MS arbeitet und mit Unicode-Problemen zu tun hat) bezeichnet ArialUni hier als "MS-Office-Schrift" und nicht als "OS-Schrift", was immer er damit meint: blogs.msdn.com/michkap/Archiv/2007/07/15/3890144.aspx

1 Stimmen

Der Vollständigkeit halber: Sie haben den Bidi-Algorithmus nicht verwendet. from bidi.algorithm import get_display; reversed = get_display(orig)

1voto

Feisal Aswad Punkte 227

Für alle Sprachen Arabisch, Hebräisch, Japanisch und sogar Englisch können Sie diesen Code verwenden:

from bidi.algorithm import get_display
import arabic_reshaper
final_text = get_display(arabic_reshaper.reshape(" "))

Dies behebt alle Probleme, aber vergessen Sie nicht, Unicode-Schriften zu verwenden, z. B. Linkbeschreibung hier eingeben

-2voto

Roman Kagan Punkte 10272

Meines Erachtens ist der Fall recht einfach. Sie können True-Type-Schriften verwenden und

Hier ein Beispiel: True-Type-Schriften für PIL

Hier finden Sie hebräische True-Type-Schriften: Hebräische True-Type-Schriften

Viel Glück oder wie wir auf Hebräisch sagen - Mazal' Tov.

0 Stimmen

Danke für Ihre Antwort, aber Sie haben die Frage nicht beantwortet. Wie ich schrieb - ich weiß, wie man TTFs schreibt, und ich habe bereits TTF-Schriften.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X