【含泪debug】manim的tex_file_writing.py文件的函数tex_to_dvi出错,导致manim渲染文字出错,无法显示文字。一个相对路径的坑

使用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.pytex_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
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在美团的Java外包面试中,面试官可能会问到一些关于待遇、加班情况、项目经验以及部门情况的问题。他们可能会询问你在项目中做了什么,使用了哪些技术和架构。他们还可能问你所面试的部门是什么,并且会让你保持电话畅通。\[1\] 此外,面试中可能会涉及到接口的概念。接口是一组规范,定义了一些方法的规则,但没有具体的方法实现。它可以用来约束类的行为,实现类需要实现接口中定义的方法。在Java中,可以使用关键字"interface"来定义接口,类可以通过实现接口来实现接口中定义的方法。\[2\] 在面试中,还可能会涉及到Lambda表达式的概念。Lambda表达式是一种简化匿名内部类的写法,可以用来实现函数式接口中的抽象方法。Lambda表达式可以简化代码,使代码更加简洁易读。\[3\] 希望这些信息对你有帮助,祝你面试顺利! #### 引用[.reference_title] - *1* [Java渣渣外包开发3年,4面终揽下美团,含泪拿到22koffer](https://blog.csdn.net/bieber007/article/details/111402943)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [2022美团秋招java面试流程,技术面题解析 看完吊打面试官](https://blog.csdn.net/Cr1556648487/article/details/126191196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值