2009-06-14 26 views
7

Pisanie prostego tekstu na obrazie przy użyciu PIL jest łatwe.Pisanie tekstu za pomocą znaków diakrytycznych ("nikud", znaków wokalizacji) za pomocą PIL (Python Imaging Library)

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

Jednak gdy próbuję napisać hebrajskie znaki interpunkcyjne (zwany „nikud” lub ניקוד), znaki nie pokrywają się tak, jak powinny. (Domyślam się, że to pytanie dotyczy także języka arabskiego i innych podobnych języków.)

W środowisku wspierającym te dwa słowa zajmują tę samą przestrzeń/szerokość (poniższy przykład zależy od systemu, a więc od obrazu):

סֶפֶר ספר

jednak podczas rysowania tekstu z PIL uzyskać:

ס ֶ פ ֶ ר

ponieważ biblioteka prawdopodobnie nie przestrzega zasad kerningu (?).

Czy możliwe jest, aby znak i hebrajski znak interpunkcyjny zajmowały tę samą przestrzeń/szerokość bez ręcznego zapisywania znaków?

image - nikud and letter spacing http://tinypic.com/r/jglhc5/5

obraz url: http://tinypic.com/r/jglhc5/5

Odpowiedz

2

śmieszne, po 5 latach, a także z wielką pomoc granic @ Nasser Al-Wohaibi, zdałem sobie sprawę, jak to zrobić:

Potrzebne było odwrócenie tekstu za pomocą algorytmu BIDI.

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

@ odpowiedź Nasera ma dodatkową wartość, która jest prawdopodobnie dotyczy tylko tekstów arabski (liter w arabskiej zmienić kształt i podłączony-ności na podstawie swych listów neiboring po hebrajsku wszystkie litery są oddzielne), więc tylko bidi części było istotne dla tego pytania.

w wyniku próbnym, Druga linia jest poprawną formą i prawidłowe pozycjonowanie znaków wokalizacji.

before and after bidi

dziękuję @tzot o pomoc + kod urywki

a-propos:

próbek różnych zachowań czcionki z hebrajskiego "nikud". Nie wszystkie czcionki zachowują się tak samo: sample PIL written, bidi hebrew text, with nikud, in different fonts

+0

Witam, miałem ** [podobny problem z użyciem Pillow] (http://stackoverflow.com/questions/41271620/the-nikud-are-not-aligned -prawidłowo-podczas-rysowania-tekstu-w-hebrajskim-użyciu-pil-pytho) **. Czy kiedykolwiek wymyśliłeś poprawkę, aby nikud był odpowiednio dopasowany, niezależnie od czcionki? – maltman

0

Wygląda mi się, że sprawa jest dość prosta. Można użyć czcionek True Type i używać

Oto przykład: True type fonts for PIL

Tutaj można znaleźć czcionki hebrajski True Type: Hebrew true type fonts

Powodzenia lub jak my mówią po hebrajsku - Mazal”Tow.

+0

Dziękuję za odpowiedź, ale nie odpowiedziałeś na pytanie. Jak napisałem - wiem, jak pisać TTF, a ja już mam czcionki TTF. –

2

W jakim systemie pracujesz? Działa to dla mnie w moim systemie Gentoo; kolejność liter jest odwrócona (po prostu skopiuj-wklejony z twojego pytania), co wydaje mi się poprawne, chociaż nie znam się na językach RTL.

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) 

produkuje:

the example text rendered as white on black http://i39.tinypic.com/2j9jxf.png

EDIT: Muszę powiedzieć, że za pomocą czcionki Deja Vu Sans nie był przypadkowy; chociaż nie podoba mi się to zbytnio (a mimo to uważam, że jego glify są lepsze niż Arial), jest czytelny, ma rozszerzony zasięg Unicode i wydaje się działać lepiej z wieloma aplikacjami innymi niż MS niż Arial Unicode MS.

+0

Tak naprawdę nie odpowiedziałeś, ale pomagasz zobaczyć błąd: Tylko DejaVuSans.ttf i Lucidaxxx.ttf zachowują się poprawnie pod PIL! Cała reszta moich plików TTF wygenerowała niepoprawne dane wyjściowe (ale ładnie się zachowują poza PIL). Możesz wypróbować inne czcionki, np. Arial.ttf –

+1

Czcionka TrueType (lub czcionka OpenType) nie musi oznaczać, że jest to kompletna i użyteczna czcionka we wszystkich aplikacjach. Michael Kaplan (pracujący obecnie dla MS i bardzo związany z problemami z Unicode) nazywa ArialUni "czcionką MS Office", a nie "czcionką OS", cokolwiek ma na myśli, tutaj: http://blogs.msdn.com/michkap/ archiwum/2007/07/15/3890144.aspx – tzot

8

chodzi arabska znaków diakrytycznych Python + Wand (Python Ilb) + arabic_reshaper (Python Ilb) + bidi.algorithme (Python Ilb).To samo odnosi się do PIL/Poduszka, trzeba użyć arabic_reshaper i bidi.algorithm i przekazać wygenerowany tekst 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

Powiązane problemy