2009-06-14 12 views
7

Escribir texto simple en una imagen usando PIL es fácil.Escribir texto con signos diacríticos ("nikud", vocalización) usando PIL (Biblioteca de imágenes de Python)

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

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

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

סֶפֶר ספר

sin embargo al dibujar el texto con PIL me sale:

ס ֶ פ ֶ ר

desde la biblioteca probablemente no obedece las reglas de interletraje (?).

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

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

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

Respuesta

2

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

Se necesitaba 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') 

@ respuesta de Nasser tiene un valor extra que probablemente es relevante sólo para textos árabes (las letras en forma de cambio árabe Y Ness conectada con base en sus cartas neiboring, en hebreo todas las letras están separados), por lo que sólo la parte bidi fue relevante para esta pregunta.

en el resultado de la muestra, la 2da línea es la forma correcta y posiciona las marcas de vocalización correctas.

before and after bidi

agradecimiento @tzot ayuda + fragmentos de código

a-propos:

muestras de diferente comportamiento de fuente con "nikud" hebreo. No todas las fuentes se comportan igual: sample PIL written, bidi hebrew text, with nikud, in different fonts

+0

Hola, he tenido un ** [problema similar con Pillow] (http://stackoverflow.com/questions/41271620/the-nikud-are-not-aligned -properly-while-drawing-text-in-hebrew-using-pil-pytho) **. ¿Alguna vez descubrió una solución para alinear correctamente el nikud independientemente de la fuente? – maltman

0

A mi me parece que el caso es bastante simple. Puede utilizar fuentes True Type y utilizar

Aquí está el ejemplo: True type fonts for PIL

Aquí puede encontrar fuentes hebreo True Type: Hebrew true type fonts

buena suerte o como nos dice en hebreo - Mazal Tov.

+0

Gracias por responder, pero no ha respondido la pregunta. Como escribí, sé cómo escribir archivos TTF, y ya tengo fuentes TTF. –

2

¿En qué sistema estás trabajando? Funciona para mí en mi sistema Gentoo; el orden de las letras se invierte (me limité a copiar y pegar de su pregunta), lo cual me parece correcto, aunque no sé mucho sobre los lenguajes 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: Debo decir que el uso de la fuente Deja Vu Sans no fue accidental; aunque no me gusta mucho (y, sin embargo, considero que sus glifos son mejores que Arial), es legible, tiene cobertura Unicode extendida y parece funcionar mejor con muchas aplicaciones que no son MS que Arial Unicode MS.

+0

No respondiste realmente, pero ayudas a ver el error: ¡Solo DejaVuSans.ttf y Lucidaxxx.ttf se comportan correctamente bajo PIL! Todos los demás archivos TTF produjeron resultados incorrectos (pero se comportan bien fuera de PIL) Puede probar otras fuentes, p. Ej. Arial.ttf –

+1

Una fuente TrueType (o fuente OpenType) no necesariamente significa que es una fuente completa y útil en todas las aplicaciones. Michael Kaplan (actualmente trabaja para MS y está muy relacionado con problemas de Unicode) llama a ArialUni una "fuente de MS Office", no una "fuente de sistema operativo", sea lo que sea que signifique, aquí: http://blogs.msdn.com/michkap/ archive/2007/07/15/3890144.aspx – tzot

8

cuanto a árabe diacríticos: Python + Wand (Python Lib) + arabic_reshaper (Python Lib) + bidi.algorithme (Python Lib).Lo mismo se aplica a PIL/Almohada, es necesario utilizar el arabic_reshaper y bidi.algorithm y aprobar 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) 

Arabic typography in images

Cuestiones relacionadas