使用 PIL(Python 图像库)编写带有变音符号(“nikud”,发声标记)的文本

发布于 2024-07-23 11:03:15 字数 659 浏览 7 评论 0原文

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

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

但是,当我尝试编写希伯来语标点符号(称为“nikud”或נйקוד)时,字符没有按应有的方式重叠。 (我猜这个问题也与阿拉伯语和其他类似语言相关。)

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

סֶפֶר ספר

但是在绘图时使用 PIL 的文本我得到:

ס ֶ פ ֶ ר,

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

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

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

图片网址:http://tinypic.com/r/jglhc5/5

Writing simple text on an image using PIL is easy.

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

However, when I try to write Hebrew punctuation marks (called "nikud" or ניקוד), the characters do not overlap as they should. (I would guess this question is relevant also to Arabic and other similar languages.)

On supporting environment, these two words take up the same space/width (the below example depends on your system, hence the image):

סֶפֶר ספר

However when drawing the text with PIL I get:

ס ֶ פ ֶ ר

since the library probably doesn't obey kerning(?) rules.

Is it possible to have the character and Hebrew punctuation mark take up the same space/width without manually writing character positioning?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤独患者 2024-07-30 11:03:15

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

图像中的阿拉伯语排版

As for Arabic diacritics : Python +Wand(Python Lib) +arabic_reshaper(Python Lib) +bidi.algorithme(Python Lib). The same applies to PIL/Pillow, you need to use the arabic_reshaper and bidi.algorithm and pass the generated text to 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

软的没边 2024-07-30 11:03:15

有趣的是,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')

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

在样本结果中,
第二行是正确的形式,以及正确的发声标记定位。

bidi 之前和之后

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

a-propos:

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

funny, after 5 years, and with great help fron @Nasser Al-Wohaibi, I realized how to do it:

Reversing the text with a BIDI algorithm was needed.

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

@Nasser's answer has extra value that's probably relevant only to arabic texts (the letters in arabic change shape and connected-ness based on their neiboring letters, in hebrew all letters are separate), so only the bidi part was relevant for this question.

in the sample result,
the 2nd line is the correct form, and correct vocalization marks positioning.

before and after bidi

thank you @tzot for help + code snippets

a-propos:

samples of different font behavior with Hebrew "nikud". Not all fonts behave the same:
sample PIL written, bidi hebrew text, with nikud, in different fonts

素衣风尘叹 2024-07-30 11:03:15

您正在使用什么系统? 它适用于我的 Gentoo 系统; 字母的顺序是相反的(我只是从你的问题中复制粘贴),这对我来说似乎是正确的,尽管我对 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)

产生:

示例文本呈现为黑底白字

编辑:我应该说使用 Deja Vu Sans 字体并不是偶然的; 虽然我不太喜欢它(但我发现它的字形比 Arial 更好),但它具有可读性,它扩展了 Unicode 覆盖范围,而且它似乎比 Arial Unicode MS更适合许多非 MS 应用程序代码>.

What system are you working on? It works for me on my Gentoo system; the order of the letters is reversed (I just copy-pasted from your question), which seems correct to me although I don't know much about RTL languages.

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)

produces:

the example text rendered as white on black

EDIT: I should say that using the Deja Vu Sans font was not accidental; although I don't like it much (and yet I find its glyphs better than Arial), it's readable, it has extended Unicode coverage, and it seems to work better with many non-MS applications than Arial Unicode MS.

青瓷清茶倾城歌 2024-07-30 11:03:15

对于所有语言阿拉伯语、希伯来语、日语甚至英语,您都可以使用此代码:

from bidi.algorithm import get_display
import arabic_reshaper
final_text = get_display(arabic_reshaper.reshape("اللغة العربية"))

这将解决所有问题,但不要忘记使用 Unicode 字体,例如 在此处输入链接说明

for all languages Arabic, Hebrew, Japanese even english you can use this code:

from bidi.algorithm import get_display
import arabic_reshaper
final_text = get_display(arabic_reshaper.reshape("اللغة العربية"))

this will fix the all problems but don't forget to use Unicode fonts such as enter link description here

路弥 2024-07-30 11:03:15

在我看来,这个案子很简单。 您可以使用 True Type 字体并使用

以下示例:PIL 的 True type 字体

在这里您可以找到希伯来语 True Type 字体:
希伯来语 true type 字体

祝你好运,或者就像我们用希伯来语说的 - Mazal' Tov。

Looks to me that the case is quite simple. You can use True Type fonts and use

Here's the example:True type fonts for PIL

Here you can find Hebrew True Type fonts:
Hebrew true type fonts

Good luck or like we saying in Hebrew - Mazal' Tov.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文