Escribir texto con diacrítico (“nikud”, marcas de vocalización) utilizando PIL (Biblioteca de imágenes de Python)

Escribir texto simple en una imagen usando PIL es fácil.

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

Sin embargo, cuando bash escribir signos de puntuación hebreos (llamados “nikud” o ניקוד), los caracteres no se superponen como deberían. (Supongo que esta pregunta es relevante también para el árabe y otros idiomas similares).

En el entorno de soporte, estas dos palabras ocupan el mismo espacio / ancho (el siguiente ejemplo depende de su sistema, de ahí la imagen):

ר ספר

Sin embargo al dibujar el texto con PIL obtengo:

ֶ פ ֶ ר

ya que la biblioteca probablemente no obedece las reglas de kerning (?).

¿Es posible que el carácter y el signo de puntuación hebreo ocupen el mismo espacio / ancho sin escribir manualmente la posición del carácter?

imagen – nikud y espaciado de letras http://tinypic.com/r/jglhc5/5

url de la imagen: http://tinypic.com/r/jglhc5/5

En cuanto a los diacríticos árabes : Python + Wand (Python Lib) + arabic_reshaper (Python Lib) + bidi.algorithme (Python Lib). Lo mismo se aplica a PIL / Almohada , debe usar el arabic_reshaper y el bidi.algorithm y pasar el texto generado a 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) 

Tipografía árabe en imágenes.

Divertido, después de 5 años, y con gran ayuda de @Nasser Al-Wohaibi, me di cuenta de cómo hacerlo:

Fue necesario revertir el texto 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') 

La respuesta de @Nasser tiene un valor adicional que probablemente sea relevante solo para los textos en árabe (las letras en árabe cambian de forma y conectan en función de sus letras de neibor, en hebreo todas las letras son separadas), por lo que solo la parte bidi fue relevante para esta pregunta.

en el resultado de la muestra, la segunda línea es la forma correcta y la posición correcta de las marcas de vocalización.

antes y despues de bidi

Gracias @tzot por ayuda + fragmentos de código

a propósito:

Muestras de comportamientos de fonts diferentes con el hebreo "nikud". No todas las fonts se comportan igual PIL de muestra escrito, texto hebreo bidi, con nikud, en diferentes fuentes

¿En qué sistema estás trabajando? Funciona para mí en mi sistema Gentoo; el orden de las letras se invierte (solo copio y copio de su pregunta), lo que me parece correcto, aunque no sé mucho acerca de los idiomas 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:

El texto de ejemplo se muestra en blanco sobre negro.

EDITAR: Debo decir que el uso de la fuente Deja Vu Sans no fue accidental; aunque no me gusta mucho (y, sin embargo, encuentro que sus glifos son mejores que Arial), es legible, ha ampliado la cobertura de Unicode y parece funcionar mejor con muchas aplicaciones que no son MS que Arial Unicode MS .

Me parece que el caso es bastante simple. Puedes usar fonts True Type y usar

Aquí está el ejemplo: fonts TrueType para PIL

Aquí puede encontrar fonts en hebreo de tipo verdadero : fonts en hebreo de tipo verdadero

Buena suerte o como decimos en hebreo – Mazal ‘Tov.