【含泪debug】manim的tex_file_writing.py文件的函数tex_to_dvi出错,导致manim渲染文字出错,无法显示文字。一个相对路径的坑
文章目录使用manim的起因遇到的问题排查错误的过程问题的解决使用manim的起因最近看了这位大佬将3b1b动画引擎的文章3Blue1Brown的动画引擎如何配置?,想要自己动手做一个动画视频。当然,做一个这个并不难,比如我按照大佬的教程,自己写的一个神经网络的示意视频。from manimlib.imports import *import osimport pyclbrclass Shapes
使用manim的起因
最近看了这位大佬将3b1b动画引擎的文章3Blue1Brown的动画引擎如何配置?,想要自己动手做一个动画视频。当然,做一个这个并不难,比如我按照大佬的教程,自己写的一个神经网络的示意视频。
from manimlib.imports import *
import os
import pyclbr
class Shapes(Scene):
#A few simple shapes
#Python 2.7 version runs in Python 3.7 without changes
def construct(self):
# 友方士兵
circle11 = Circle(color=RED_A, radius=0.5)
circle11.move_to(UP*3+LEFT*2)
circle12 = Circle(color=RED_A, radius=0.5)
circle12.move_to(LEFT*2)
circle13 = Circle(color=RED_A, radius=0.5)
circle13.move_to(DOWN*3+LEFT*2)
# 敌方士兵
circle21 = Circle(color=GREEN_A, radius=0.5)
circle21.move_to(UP*2+RIGHT*2)
circle22 = Circle(color=GREEN_A, radius=0.5)
circle22.move_to(DOWN*2+RIGHT*2)
# 攻击箭头
arrow11 = Arrow(start=circle11,end=circle21,color=WHITE,stroke_width=3)
arrow12 = Arrow(start=circle11,end=circle22,color=WHITE,stroke_width=3)
arrow21 = Arrow(start=circle12,end=circle21,color=WHITE,stroke_width=3)
arrow22 = Arrow(start=circle12,end=circle22,color=WHITE,stroke_width=3)
arrow31 = Arrow(start=circle13,end=circle21,color=WHITE,stroke_width=3)
arrow32 = Arrow(start=circle13,end=circle22,color=WHITE,stroke_width=3)
# 显示过程
self.play(ShowCreation(circle11), ShowCreation(circle12), ShowCreation(circle13))
self.play(ShowCreation(circle21), ShowCreation(circle22))
self.play(GrowArrow(arrow11), GrowArrow(arrow12))
self.play(GrowArrow(arrow21), GrowArrow(arrow22))
self.play(GrowArrow(arrow31), GrowArrow(arrow32))
if __name__ == "__main__":
module_name = 'my_manim_test1' #Name of current file
for item in module_info.values():
if item.module==module_name:
print(item.name)
os.system("python -m manim my_manim_test1.py %s -pl" % item.name) #Does not play files
遇到的问题
然而在渲染文字时,我遇到了困难。按照大佬的教程,我执行代码python -m manim manim_tutorial_P37.py AddingText -pl
,结果遇到了如下报错——
Traceback (most recent call last):
File "E:\manim-3b1b\manim-master\manimlib\extract_scene.py", line 155, in main
scene = SceneClass(**scene_kwargs)
File "E:\manim-3b1b\manim-master\manimlib\scene\scene.py", line 53, in __init__
self.construct()
File "manim_tutorial_P37.py", line 64, in construct
my_first_text=TextMobject("Writing with manim is fun")
File "E:\manim-3b1b\manim-master\manimlib\mobject\svg\tex_mobject.py", line 148, in __init__
self, self.arg_separator.join(tex_strings), **kwargs
File "E:\manim-3b1b\manim-master\manimlib\mobject\svg\tex_mobject.py", line 44, in __init__
self.template_tex_file_body
File "E:\manim-3b1b\manim-master\manimlib\utils\tex_file_writing.py", line 19, in tex_to_svg_file
dvi_file = tex_to_dvi(tex_file)
File "E:\manim-3b1b\manim-master\manimlib\utils\tex_file_writing.py", line 68, in tex_to_dvi
"See log output above or the log file: %s" % log_file)
Exception: Latex error converting to dvi. See log output above or the log file: ./media\Tex\9e7a6968d7bc54fd.log
排查错误的过程
一步一步排查原因,发现根本原因在于E:\manim-3b1b\manim-master\manimlib\utils\tex_file_writing.py
的tex_to_dvi
函数出错了。
检查地址E:\manim-3b1b\manim-master\media\Tex
的输出文件,发现9e7a6968d7bc54fd.tex
确实有,但其他的啥都没有,连9e7a6968d7bc54fd.log
都没有。
最开始怀疑是原装 LaTeX \LaTeX LATEX可能不行,结果装了新版本的MiKTeX,发现还是不行,MiKTeX也能在命令行中显示版本,dvisvgm版本也能显示。在网上找解决方案,基本都试了个遍,都不行。这bug差点给我整破防了,差点想放弃manim了。
然后,我尝试了下用TeXworks editor编译了下文件9e7a6968d7bc54fd.tex
,发现能够正常编译出来,当然我用的是pdfLaTeX。然后在命令行里用绝对路径latex E:\manim-3b1b\manim-master\media\Tex\9e7a6968d7bc54fd.tex
执行,发现也能正确输出。但cd /d E:\manim-3b1b\manim-master\
后用相对路径latex ./media\Tex\9e7a6968d7bc54fd.tex
编译就会显示找不到文件,这就奇了怪了。
仔细思考,md,这个错误和我上午命令行里用anaconda prompt执行python xxx.py
找不到文件一个道理吗?这里的相对路径并不是相对于我的xxx.py
的路径,而是相对于python.exe
的路径。这个问题真是太蠢了!
仔细检查,发现原本的tex_to_dvi
函数是
def tex_to_dvi(tex_file):
result = tex_file.replace(".tex", ".dvi" if not TEX_USE_CTEX else ".xdv")
if not os.path.exists(result):
commands = [
"latex",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=\"{}\"".format(consts.TEX_DIR),
"\"{}\"".format(tex_file),
">",
os.devnull
] if not TEX_USE_CTEX else [
"xelatex",
"-no-pdf",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=\"{}\"".format(consts.TEX_DIR),
"\"{}\"".format(tex_file),
">",
os.devnull
]
exit_code = os.system(" ".join(commands))
if exit_code != 0:
log_file = tex_file.replace(".tex", ".log")
raise Exception(
("Latex error converting to dvi. " if not TEX_USE_CTEX
else "Xelatex error converting to xdv. ") +
"See log output above or the log file: %s" % log_file)
return result
问题的解决
问题就出现在commands
里,"-output-directory=\"{}\"".format(consts.TEX_DIR)
相当于./media\Tex\9e7a6968d7bc54fd.tex
,也就是说,这是相对路径。那么**这个相对路径是相对于谁呢?**其实是相对于tex.exe
的路径,而不是.py
文件的相对路径。所以解决方案也呼之欲出了,把"\"{}\"".format(tex_file),
改成"\""+os.path.dirname(os.path.dirname(__file__))+"\\."+tex_file+"\""
就可以了。芜湖,问题解决了,准备睡觉咯。
下面附上正确的完整代码——
def tex_to_dvi(tex_file):
result = tex_file.replace(".tex", ".dvi" if not TEX_USE_CTEX else ".xdv")
if not os.path.exists(result):
commands = [
"latex",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=\"{}\"".format(consts.TEX_DIR),
"\""+os.path.dirname(os.path.dirname(__file__))+"\\."+tex_file+"\"",
">",
os.devnull
] if not TEX_USE_CTEX else [
"xelatex",
"-no-pdf",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=\"{}\"".format(consts.TEX_DIR),
"\"{}\"".format(tex_file),
">",
os.devnull
]
exit_code = os.system(" ".join(commands))
if exit_code != 0:
log_file = tex_file.replace(".tex", ".log")
raise Exception(
("Latex error converting to dvi. " if not TEX_USE_CTEX
else "Xelatex error converting to xdv. ") +
"See log output above or the log file: %s" % log_file)
return result
更多推荐
所有评论(0)