使用PIL(Python成像库)使用变音符号("nikud",发声标记)编写文本

Ber*_*ala 7 python unicode fonts hebrew python-imaging-library

使用PIL在图像上编写简单文本很容易.

draw = ImageDraw.Draw(img)
draw.text((10, y), text2, font=font, fill=forecolor )
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试写希伯来语标点符号(称为"nikud"或ניקוד)时,字符不会重叠.(我猜这个问题也与阿拉伯语和其他类似语言有关.)

在支持环境中,这两个词占用相同的空间/宽度(以下示例取决于您的系统,因此图像):

סֶפֶרספר

但是当用PIL绘制文本时,我得到:

סֶפֶר

因为库可能不遵守字距调整(?)规则.

是否可以让字符和希伯来语标点符号占用相同的空间/宽度而无需手动编写字符定位?

image - nikud和字母间距http://tinypic.com/r/jglhc5/5

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

Nas*_*ibi 8

至于阿拉伯语变音符号:Python + Wand(Python Lib)+ arabic_reshaper(Python Lib)+ bidi.algorithme(Python Lib).这同样适用于PIL/Pillow,您需要使用arabic_reshaperand bidi.algorithm并将生成的文本传递给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)
Run Code Online (Sandbox Code Playgroud)

图像中的阿拉伯语排版


Ber*_*ala 5

有趣的是,5 年后,在@Nasser Al-Wohaibi 的大力帮助下,我意识到了如何去做:

需要使用 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')
Run Code Online (Sandbox Code Playgroud)

@Nasser 的答案具有额外的价值,可能仅与阿拉伯语文本相关(阿拉伯语中的字母根据其相邻字母改变形状和连通性,在希伯来语中所有字母都是分开的),因此只有 bidi 部分与此问题相关。

在示例结果中,第 2 行是正确的形式,正确的发声标记定位。

比迪之前和之后

谢谢@tzot 的帮助 + 代码片段

a-提案:

使用希伯来语“nikud”的不同字体行为示例。并非所有字体的行为都相同: 示例 PIL 书写,bidi 希伯来语文本,带有 nikud,不同字体