使用 Pillow 绘制草书文本
Using Pillow to draw cursive text
我要在 Ubuntu 14.04 LTS
机器上托管的 Django 应用程序中的图像上绘制文本。 Pillow 4.2.1
是我选择的库。
我已经通过从PIL
导入的ImageDraw
成功完成了这个任务(实际代码在这个问题的最后)
我的代码非常适合英语、法语或西班牙语等语言。
但不适用于自然草书 语言,如阿拉伯语、波斯语或乌尔都语。在这种情况下,它会分别绘制每个字母。例如。 فارسی
(波斯语)绘制为:
请注意,我为此安装了 sudo apt-get install ttf-mscorefonts-installer
并尝试了 /fonts/truetype/msttcorefonts/Arial.ttf
。
有人 advised me 确保我使用的字体有 连字。我的理解是 Arial
确实支持连字,但问题仍然存在。
我的问题是:我应该怎么做才能解决这个问题?我的代码必须支持自然草书语言,如阿拉伯语、波斯语或乌尔都语。
代码:
from PIL import ImageDraw
draw = ImageDraw.Draw(img)
base_width, base_height = img.size
y = 2
for line in lines:
width, height = font.getsize(line)
x = (base_width - width) / 2
text_with_stroke(draw,x,y,line,font,fillcolor,shadowcolor)
y += height
其中 text_with_stroke
就是:
def text_with_stroke(draw,width,height,line,font,fillcolor,shadowcolor):
draw.text((width-1, height), line, font=font, fill=shadowcolor)
draw.text((width+1, height), line, font=font, fill=shadowcolor)
draw.text((width, height-1), line, font=font, fill=shadowcolor)
draw.text((width, height+1), line, font=font, fill=shadowcolor)
draw.text((width, height), line, font=font, fill=fillcolor)
简而言之,这段代码将任何给定的文本分成单独的行,同时考虑到字体大小和底层图像大小。然后它迭代地在图像上绘制每一行文本。
这个问题的最佳答案已经在这个相当优秀的 SO post: 上解决了。
基本上,这里需要两个 Python 库:BiDi
和 Arabic Reshaper
。
那是 pip install python-bidi
和 pip install git+https://github.com/mpcabd/python-arabic-reshaper
。确切的实现需要在通过 PIL
:
绘制之前按如下方式转换 text
reshaped_text = arabic_reshaper.reshape(line)
final_text = get_display(reshaped_text)
draw.text((width-1, height), final_text, font=font, fill=shadowcolor)
draw.text((width+1, height), final_text, font=font, fill=shadowcolor)
draw.text((width, height-1), final_text, font=font, fill=shadowcolor)
draw.text((width, height+1), final_text, font=font, fill=shadowcolor)
draw.text((width, height), final_text, font=font, fill=fillcolor)
我要在 Ubuntu 14.04 LTS
机器上托管的 Django 应用程序中的图像上绘制文本。 Pillow 4.2.1
是我选择的库。
我已经通过从PIL
导入的ImageDraw
成功完成了这个任务(实际代码在这个问题的最后)
我的代码非常适合英语、法语或西班牙语等语言。
但不适用于自然草书 语言,如阿拉伯语、波斯语或乌尔都语。在这种情况下,它会分别绘制每个字母。例如。 فارسی
(波斯语)绘制为:
请注意,我为此安装了 sudo apt-get install ttf-mscorefonts-installer
并尝试了 /fonts/truetype/msttcorefonts/Arial.ttf
。
有人 advised me 确保我使用的字体有 连字。我的理解是 Arial
确实支持连字,但问题仍然存在。
我的问题是:我应该怎么做才能解决这个问题?我的代码必须支持自然草书语言,如阿拉伯语、波斯语或乌尔都语。
代码:
from PIL import ImageDraw
draw = ImageDraw.Draw(img)
base_width, base_height = img.size
y = 2
for line in lines:
width, height = font.getsize(line)
x = (base_width - width) / 2
text_with_stroke(draw,x,y,line,font,fillcolor,shadowcolor)
y += height
其中 text_with_stroke
就是:
def text_with_stroke(draw,width,height,line,font,fillcolor,shadowcolor):
draw.text((width-1, height), line, font=font, fill=shadowcolor)
draw.text((width+1, height), line, font=font, fill=shadowcolor)
draw.text((width, height-1), line, font=font, fill=shadowcolor)
draw.text((width, height+1), line, font=font, fill=shadowcolor)
draw.text((width, height), line, font=font, fill=fillcolor)
简而言之,这段代码将任何给定的文本分成单独的行,同时考虑到字体大小和底层图像大小。然后它迭代地在图像上绘制每一行文本。
这个问题的最佳答案已经在这个相当优秀的 SO post: 上解决了。
基本上,这里需要两个 Python 库:BiDi
和 Arabic Reshaper
。
那是 pip install python-bidi
和 pip install git+https://github.com/mpcabd/python-arabic-reshaper
。确切的实现需要在通过 PIL
:
text
reshaped_text = arabic_reshaper.reshape(line)
final_text = get_display(reshaped_text)
draw.text((width-1, height), final_text, font=font, fill=shadowcolor)
draw.text((width+1, height), final_text, font=font, fill=shadowcolor)
draw.text((width, height-1), final_text, font=font, fill=shadowcolor)
draw.text((width, height+1), final_text, font=font, fill=shadowcolor)
draw.text((width, height), final_text, font=font, fill=fillcolor)