2009-06-14 16 views
7

Scrivere un testo semplice su un'immagine utilizzando PIL è semplice.Scrittura del testo con diacritico ("nikud", segni di vocalizzazione) utilizzando PIL (Python Imaging Library)

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

Tuttavia, quando provo a scrivere i segni di punteggiatura ebraico (chiamato "nikud" o ניקוד), i personaggi non si sovrappongono come dovrebbero. (Direi che questa domanda è rilevante anche per l'arabo e altre lingue simili.)

In ambiente di supporto, queste due parole occupano lo stesso spazio/larghezza (l'esempio seguente dipende dal sistema, quindi dall'immagine):

סֶפֶר ספר

Tuttavia quando si disegna il testo con PIL ottengo:

ס ֶ פ ֶ ר

dal momento che la biblioteca probabilmente non obbedisce crenatura regole (?).

E 'possibile che il carattere e il segno di punteggiatura ebraico occupino lo stesso spazio/larghezza senza scrivere manualmente il posizionamento dei caratteri?

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

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

risposta

2

divertente, dopo 5 anni, e con grande aiuto fron @ Nasser Al-Wohaibi, mi sono reso conto di come farlo:

È stata necessaria l'inversione del testo con un algoritmo 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') 

@ risposta di Nasser ha valore in più che probabilmente è rilevante solo per testi arabi (le lettere in forma cambiamento araba e-ness collegati in base alle loro lettere neiboring, in ebraico tutte le lettere sono separati), in modo che solo la parte bidi era rilevante per questa domanda.

nel risultato del campione, la seconda riga è la forma corretta e il corretto posizionamento dei segni di vocalizzazione.

before and after bidi

ringraziamento @tzot aiuto + frammenti di codice

a-propos:

campioni di diversi comportamenti di carattere con l'ebraico "nikud". Non tutti i tipi di carattere si comportano allo stesso modo: sample PIL written, bidi hebrew text, with nikud, in different fonts

+0

Ciao a tutti, ho avuto un ** [problema simile usando Pillow] (http://stackoverflow.com/questions/41271620/the-nikud-are-non-allineato -properly-mentre-disegno-text-in-ebraico-con-pil-Pytho) **. Hai mai trovato una soluzione per far sì che il nikud fosse allineato correttamente indipendentemente dal carattere? – maltman

0

a me sembra che il caso è abbastanza semplice. È possibile utilizzare i font True Type e utilizzare

Ecco l'esempio: True type fonts for PIL

Qui potete trovare i caratteri Hebrew True Type: Hebrew true type fonts

Buona fortuna o come abbiamo detto in ebraico - Mazal' Tov.

+0

Grazie per la risposta, ma non hai risposto alla domanda. Come ho scritto, so come scrivere TTF e ho già i font TTF. –

2

Su quale sistema stai lavorando? Funziona per me sul mio sistema Gentoo; l'ordine delle lettere è invertito (ho appena copiato e incollato dalla tua domanda), il che mi sembra corretto anche se non ne so molto dei linguaggi 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) 

produce:

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

EDIT: Devo dire che utilizzando il carattere Deja Vu Sans non è stata casuale; anche se non mi piace molto (e tuttavia trovo i suoi glifi meglio di Arial), è leggibile, ha esteso la copertura Unicode e sembra funzionare meglio con molte applicazioni non MS rispetto allo Arial Unicode MS.

+0

In realtà non hai risposto, ma aiutaci a vedere il bug: Solo DejaVuSans.ttf e Lucidaxxx.ttf si comportano correttamente in PIL! Tutti gli altri file TTF hanno prodotto output errati (ma si comportano bene all'esterno del PIL) Puoi provare altri tipi di carattere, ad es. Arial.ttf –

+1

Un carattere TrueType (o carattere OpenType) non significa necessariamente che sia un font completo e utile in tutte le applicazioni. Michael Kaplan (che lavora attualmente per MS e molto legato ai problemi Unicode) chiama ArialUni come "font MS Office", non come "font del SO", qualunque cosa voglia dire, qui: http://blogs.msdn.com/michkap/ archivio/2007/07/15/3890144.aspx – tzot

8

Per quanto riguarda arabo segni diacritici: Python + Wand (Python Lib) + arabic_reshaper (Python Lib) + bidi.algorithme (Python Lib).Lo stesso vale per PIL/cuscino, è necessario utilizzare il arabic_reshaper e bidi.algorithm e passare il testo generato per 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

Problemi correlati