mirror of
https://github.com/3b1b/manim.git
synced 2025-09-19 04:41:56 +00:00
Ability to export PNG sequence
While writing to a movie file, if you specify -f it will export a png sequence in a folder with the same name like the scene. The ability to export transparent PNG sequences adds the ability to change the background afterwards.
This commit is contained in:
parent
87801c2ed8
commit
c7214005ae
2 changed files with 31 additions and 5 deletions
|
@ -24,6 +24,8 @@ HELP_MESSAGE = """
|
|||
-m use medium quality
|
||||
-a run and save every scene in the script, or all args for the given scene
|
||||
-q don't print progress
|
||||
-f when writing to a movie file, export the frames in png sequence
|
||||
-t use transperency when exporting images
|
||||
"""
|
||||
SCENE_NOT_FOUND_MESSAGE = """
|
||||
That scene is not in the script
|
||||
|
@ -42,7 +44,7 @@ NO_SCENE_MESSAGE = """
|
|||
|
||||
def get_configuration(sys_argv):
|
||||
try:
|
||||
opts, args = getopt.getopt(sys_argv[1:], 'hlmpwstqao:')
|
||||
opts, args = getopt.getopt(sys_argv[1:], 'hlmpwfstqao:')
|
||||
except getopt.GetoptError as err:
|
||||
print(str(err))
|
||||
sys.exit(2)
|
||||
|
@ -55,6 +57,7 @@ def get_configuration(sys_argv):
|
|||
"write_to_movie" : False,
|
||||
"save_frames" : False,
|
||||
"save_image" : False,
|
||||
"save_pngs" : False,
|
||||
#If -t is passed in (for transparent), this will be RGBA
|
||||
"saved_image_mode": "RGB",
|
||||
"quiet" : False,
|
||||
|
@ -76,6 +79,8 @@ def get_configuration(sys_argv):
|
|||
config["frame_duration"] = MEDIUM_QUALITY_FRAME_DURATION
|
||||
if opt == '-w':
|
||||
config["write_to_movie"] = True
|
||||
if opt == '-f': #pngs
|
||||
config["save_pngs"] = True
|
||||
if opt == '-s':
|
||||
config["save_image"] = True
|
||||
if opt == '-t':
|
||||
|
@ -86,6 +91,7 @@ def get_configuration(sys_argv):
|
|||
config["write_all"] = True
|
||||
if opt == '-o':
|
||||
config["output_name"] = arg
|
||||
|
||||
#By default, write to file
|
||||
actions = ["write_to_movie", "preview", "save_image"]
|
||||
if not any([config[key] for key in actions]):
|
||||
|
@ -184,6 +190,7 @@ def main():
|
|||
scene_names_to_classes = dict(
|
||||
inspect.getmembers(module, is_scene)
|
||||
)
|
||||
|
||||
config["output_directory"] = os.path.join(
|
||||
MOVIE_DIR,
|
||||
config["file"].replace(".py", "")
|
||||
|
@ -198,9 +205,16 @@ def main():
|
|||
"write_to_movie",
|
||||
"save_frames",
|
||||
"output_directory",
|
||||
"save_pngs"
|
||||
]
|
||||
])
|
||||
|
||||
scene_kwargs["name"] = config["output_name"]
|
||||
if config["save_pngs"]:
|
||||
print "We are going to save a PNG sequence as well..."
|
||||
scene_kwargs["save_pngs"] = True
|
||||
scene_kwargs["pngs_mode"] = config["saved_image_mode"]
|
||||
|
||||
for SceneClass in get_scene_classes(scene_names_to_classes, config):
|
||||
try:
|
||||
handle_scene(SceneClass(**scene_kwargs), **config)
|
||||
|
|
|
@ -30,6 +30,8 @@ class Scene(object):
|
|||
"skip_animations" : False,
|
||||
"write_to_movie" : False,
|
||||
"save_frames" : False,
|
||||
"save_pngs" : False,
|
||||
"pngs_mode" : "RGBA",
|
||||
"output_directory" : MOVIE_DIR,
|
||||
"name" : None,
|
||||
"always_continually_update" : False,
|
||||
|
@ -44,6 +46,7 @@ class Scene(object):
|
|||
self.num_plays = 0
|
||||
self.saved_frames = []
|
||||
self.shared_locals = {}
|
||||
self.frame_num = 0
|
||||
if self.name is None:
|
||||
self.name = self.__class__.__name__
|
||||
if self.random_seed is not None:
|
||||
|
@ -447,6 +450,9 @@ class Scene(object):
|
|||
def add_frames(self, *frames):
|
||||
if self.write_to_movie:
|
||||
for frame in frames:
|
||||
if self.save_pngs:
|
||||
self.save_image("frame" + str(self.frame_num), self.pngs_mode, True)
|
||||
self.frame_num = self.frame_num + 1
|
||||
self.writing_process.stdin.write(frame.tostring())
|
||||
if self.save_frames:
|
||||
self.saved_frames += list(frames)
|
||||
|
@ -459,14 +465,19 @@ class Scene(object):
|
|||
|
||||
def preview(self):
|
||||
TkSceneRoot(self)
|
||||
|
||||
def save_image(self, name = None, mode = "RGB", dont_update = False):
|
||||
folder = "images"
|
||||
if dont_update:
|
||||
folder = str(self)
|
||||
|
||||
def save_image(self, name = None, mode = "RGB"):
|
||||
path = os.path.join(self.output_directory, "images")
|
||||
path = os.path.join(self.output_directory, folder)
|
||||
file_name = (name or str(self)) + ".png"
|
||||
full_path = os.path.join(path, file_name)
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
self.update_frame()
|
||||
if not dont_update:
|
||||
self.update_frame()
|
||||
image = self.get_image()
|
||||
image = image.convert(mode)
|
||||
image.save(full_path)
|
||||
|
@ -505,7 +516,8 @@ class Scene(object):
|
|||
'-loglevel', 'error',
|
||||
temp_file_path,
|
||||
]
|
||||
self.writing_process = sp.Popen(command, stdin=sp.PIPE)
|
||||
|
||||
self.writing_process = sp.Popen(command, stdin=sp.PIPE, shell=True)
|
||||
|
||||
def close_movie_pipe(self):
|
||||
self.writing_process.stdin.close()
|
||||
|
|
Loading…
Add table
Reference in a new issue