I had been trying to animate bengali characters using Manim. I used this method to use pc fonts in Manim. Everything seemed to be working well until i saw the output. For instance, if i write বাংলা লেখা i get the output as (look closely at the output) বাংলা লখো. Most of the times it spits out absolutely meaningless words.
The code used was:
class test_3(Scene):
def construct(self):
text1 = Text('বাংলা লেখা', font='Akaash')
text2 = Text('english text', font='Arial').move_to(DOWN)
self.play(Write(text1), Write(text2))
self.wait()
Bangla texts can be displayed properly just by specifying a Bangla font in Text() or MarkupText().
For example, if I like to display the Bangla text আইনস্টাইনের সমীকরণ in Kalpurush font, it can be done by:
from manim import *
class bangla(Scene):
def construct(self):
text = Text("আইনস্টাইনের সমীকরণ", font="Kalpurush")
self.play(Write(text))
Here, the font is locally installed. Many fonts can be used directly from online via the python package manim-fonts.
If you want to nicely show Bangla texts/sentences that contain inline-maths, you can use the LaTeX package latexbangla.
Here's an example code:
from manim import *
class bangla(Scene):
def construct(self):
myTemplate = TexTemplate(tex_compiler="xelatex", output_format=".pdf", preamble=r"\usepackage[banglamainfont=Kalpurush, banglattfont=Kalpurush]{latexbangla}")
tex = Tex(r"আইনস্টাইনের সমীকরণ, $E^2=(mc^2)^2+(pc)^2$", tex_template=myTemplate)
self.play(Write(tex))
The output:
N.B. The issue was also discussed on the Github repositories: ManimCommunity/manim and 3b1b/maim.
This is because of font type.
You should use bangli font. Try any font from here
Try to use ANSI Bangla fonts like "SutonnyMJ". If you are using Avro keyboard you can use Output as ANSI option like this,
Then if you have chosen font for example "SutonnyMJ", your code should look like this,
class test_3(Scene):
def construct(self):
text1 = Text('evsjv †jKAv', font='SutonnyMJ')
text2 = Text('english text', font='Arial').move_to(DOWN)
self.play(Write(text1), Write(text2))
self.wait()
Here I've replaced বাংলা লেখা with evsjv †jKAv (just ANSI form of the same Unicode text) which will render বাংলা লেখা as the font is now ANSI. I hope that Manim will support unicode fonts soon.
EDIT
I've found Bengali Unicode fonts to be working on Manim now. (24 March, 2021). I did this with Kalpurush font.
The code is
class FirstScene(Scene):
def construct(self):
text = Text("বাংলা অক্ষরে লেখা", font="Kalpurush")
text2 = Text("Another text")
self.play(Write(text), run_time=1)
self.wait(3)
self.remove(text)
self.play(Write(text2))
See the screenshot below,
Related
I made a custom handwriting font and exported it to a .ttf file. The service I used, Caligriphr, allows for alternate glyphs for each character. When I type with the font in notepad, alternate glyphs display correctly. However, when I write text onto an image using PIL with the custom font, only one glyph is used
for each character. Below is my code to write on the image:
body = ""
with open('body.txt') as fin:
ls = fin.readlines()
for l in ls:
words = l.split(' ')
for word in words:
double = random.randint(1,2) == 2
if(double):
body += ' ' + word
else:
body += ' ' + word
image = Image.open('graph.jpg').convert("RGBA")
text = Image.new('RGBA', image.size, (255,255,255,0))
font = ImageFont.FreeTypeFont('Graphite.ttf', 100)
d = ImageDraw.Draw(text)
d.text(xy=offset, text=body, fill = (26,29,32, 230), font=font)
tilt = random.random() * 2
slt = text.rotate(tilt, expand=1)
sx, sy = slt.size
image.paste(slt, (0,0, sx, sy), slt)
image.save('sample.png')
Edit: showing code for how body string is constructed
Any help would be appreciated.
Alternate Glyphs Displayed in Notepad
PIL output not utilizing alternate glyphs
This may depend on whether you're using the original PIL library, or Pillow.
Getting contextual alternate glyphs in the drawn output requires that the rendering engine draw the string as an entire string (not character by character) and, while doing so, process certain data in the font that performs glyph substitutions from the default glyphs.
This data could be OpenType Layout tables in OpenType fonts, AAT tables in Apple TrueType fonts, or Graphite tables in Graphite fonts, depending on what the platform/library supports. Since you mention you got alternates in Notepad, that indicates that the font has OpenType Layout data.
Reading the Pillow ImageFont documentation, it doesn't give any indication as to whether it supports any of these font formats. However, looking at the Pillow project in Github, I see that [winbuild\config.py] pulls in Harfbuzz, and that would provide support for OpenType Layout data. So, it seems that Pillow ought to draw using the contextual alternate glyphs, though I don't know if anything is needed to trigger it. (In Notepad, it happens by default, but that's not true everywhere.)
If using Pillow, you might need to explicitly enable the Raqm layout engine when loading the font: "Raqm - A library for complex text layout" http://host-oman.github.io/libraqm/raqm-Raqm.html
This engine can be specified using the ImageFont.truetype() function:
font = ImageFont.truetype('Graphite.ttf', 100, layout_engine=ImageFont.LAYOUT_RAQM)
Docs: https://pillow.readthedocs.io/en/stable/reference/ImageFont.html#PIL.ImageFont.truetype
Testing if Raqm is availble on your system:
>>> from PIL import features
>>> features.check('raqm')
True
If not available, on my Ubuntu 20 it installs via
$ sudo apt install libraqm0
Edit: It looks like you don't even have to specify the layout_engine parameter at all. On my system alternate glyphs are used as soon as I install the Raqm library, even without changing the code.
I'm trying to display non English characters in movie py but it's not displaying the actual character I typed. The language I'm trying is Telugu. What is the problem in displaying the characters?
This is the code I'm using
# -*- coding: utf-8 -*-
from moviepy.editor import *
# create clip from image
clip = ImageClip('img/1.jpg').on_color((1920, 1080))
clip = clip.set_duration(2)
# add annotation to clip
txtclip = TextClip('n+<ý² yûTq¿£yû', fontsize=50, color='red', font="Deepika")
cvc = CompositeVideoClip([ clip, txtclip.set_pos(('center', 'bottom'))])
cvc = cvc.set_duration(2)
# write video to file
cvc.write_videofile("text.mp4", fps=24)
The characters(Language) displayed in the code is weird but when I copy the text from the original file which was different characters displayed as this. And this worked in displaying the text in PySide QLabel.
Its just displaying boxes instead of the characters.
Can anyone help me with this issue?For your reference I'm adding image of text displayed in the code for language
I had a similar problem. I printed Japanese characters, but they were not displayed in video.
The problem was that the font did not support these characters.
Thus this produced empty result:
my_text = mp.TextClip("すみません。お先に失礼します",
font= "Amiri-regular", color= "white", fontsize= 34)
Solution was to download a custom font and import it as in example:
my_text2 = mp.TextClip("すみません。お先に失礼します",
font="wqy-microhei.ttc", color="white", fontsize=34)
I downloaded this font from github and it can be simply placed into directory with the python source code to be imported.
I am handing off font data from one application to another, and unfortunately the first application is only able to give me "postscript" font names and nothing else. What I need is to find the filename on disk of the postscript font name. For example I have the postscript name "ZoomlaYingXing-A024" which is called "ZhuLang Semi-Cursive Script Chinese Font.otf" on my hard drive.
The second application is written in PyQt4 and ideally I could use some of the tools in Qt to handle this. For example I can construct a QFont from the font name, and query QFont.exactMatch() to make sure that I get THAT font - and from there I could create a QFontInfo object, however the only useful data I seem to be able to get out of a QFontInfo object is rawName() which just gives me the postscript name again...
From reading around it looks like I could search the registry but I have never worked with the registry and the examples I found were written in C++ which I'm not sure how to translate.
For info this only needs to work on Windows.
You could use fontTools and matplotlib.
If you need any more information about how to decode the font postscript, see the answer I posted here: How to get the font name (title) from a font file in python
from matplotlib import font_manager
from fontTools import ttLib
def isFontMatchPostscriptName(fontPath: str, font: ttLib.TTFont):
postScriptName = font['name'].getDebugName(6)
if postScriptName == "Cambria":
print("The font is located in: ", fontPath)
fontsPath = font_manager.findSystemFonts()
for fontPath in fontsPath:
with open(fontPath, 'rb') as fontFile:
fontType = fontFile.read(4)
if fontType == (b'ttcf'):
# TTC File.
ttCollection = ttLib.ttCollection.TTCollection(fontPath)
for font in ttCollection.fonts:
isFontMatchPostscriptName(fontPath, font)
else:
# It will be any TrueType or OpenType file except TTC file
isFontMatchPostscriptName(fontPath, ttLib.TTFont(fontPath))
The function in question:
PIL.ImageDraw.Draw.text(xy, text, fill=None, font=None, anchor=None)
The issue is pretty standard... gibberish:
Right now, I'm running a string (utf-8) into the draw text function above, but it's giving all those weird characters. However, if I just print it, it shows the characters fine.
Should I pass a Unicode object instead?
This works correctly on Python 3.6.2 and 2.7.13 with pillow-4.2.1 (strings are default Unicode in Python 3.x). Chinese didn't display with the default font, but Arial MS Unicode worked.
#coding:utf8
from PIL import Image,ImageDraw,ImageFont
im = Image.new('1',(100,100))
draw = ImageDraw.Draw(im)
font = ImageFont.truetype(font='ARIALUNI.TTF',size=20)
draw.text((0,0),u'马克','white',font=font)
im.show()
Output:
I'm having difficulty making ReportLab render Chinese Characters. From everything I've looked up people are saying that it is probably a font problem but I've used a lot of different fonts and it doesn't even seem to be using them at all. The Chinese characters always just come out as black squares. Below is some sample code of what I have.
# -*- coding: utf8 -*-
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO
pdfmetrics.registerFont(TTFont('Arial', 'arial.ttf', 'UTF-8'))
buffer = BytesIO()
doc = SimpleDocTemplate(buffer,
rightMargin=inch*0.5, # 1/2 Inch
leftMargin=inch*0.5, # 1/2 Inch
bottomMargin=0,
topMargin=inch*0.375, # 3/8 Inch
pagesize=letter)
# Get Styles
styles = getSampleStyleSheet()
# Custom Style
styles.add(ParagraphStyle(name='Address', font='Arial', fontSize=8))
elements = []
elements.append(Paragraph(u'6905\u897f\u963f\u79d1\u8857\uff0c\u5927\u53a6\uff03\u5927', styles['Address']))
doc.build(elements)
# Get the value of the BytesIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
return pdf
I'm using an arial.ttf font found on my Ubuntu 12.04 installation in the fonts folder. I have also tried other fonts installed on this machine and all have exactly the same look even on the numbers and none of the Chinese characters are anything other than black squares.
Am I registering fonts wrong if even the numbers at the beginning aren't printing correctly? What could be causing the black squares?
Solved it. Turns out in your ParagraphStyle it needs to be fontName="Arial" not font="Arial" but I did learn some other tricks of getting it to work in other ways below.
styles.add(ParagraphStyle(name='Address', fontName='Arial')
After doing some digging I've learned a few things that I hope helps someone else in this situation. When you add the tags inside of your Paragraph around the Unicode text and set it explicitly to a font it will work.
elements.append(Paragraph(u'<font name="Arial">6905\u897f\u963f\u79d1\u8857\uff0c\u5927\u53a6\uff03\u5927</font>', styles['Address']))
This fixes the problem at least for Paragraphs with various fonts.
Again this code will work.
Choose the fonts that supports Chinese characters.
In Ubuntu, I choose "AR PL UMing CN" for example.
My code snippets:
# -*- coding: utf-8 -*-
...
pdfmetrics.registerFont(TTFont('AR PL UMing CN', 'uming.ttc'))
styles = getSampleStyleSheet()
...
styles.add(ParagraphStyle(name='Chinese', fontName='AR PL UMing CN', fontSize=20))
elements=[]
elements.append(Paragraph("成”, styles['Chinese']))
doc.build(elements)
...
I can even change to Chinese editor and type in the character straight off. Hope this helps.