Consolidate camera configuration

This commit is contained in:
Grant Sanderson 2024-12-10 11:39:13 -06:00
parent d4c5c4736a
commit 4cc2e5ed17
4 changed files with 42 additions and 44 deletions

View file

@ -8,7 +8,7 @@ from PIL import Image
from manimlib.camera.camera_frame import CameraFrame from manimlib.camera.camera_frame import CameraFrame
from manimlib.constants import BLACK from manimlib.constants import BLACK
from manimlib.constants import DEFAULT_FPS from manimlib.constants import DEFAULT_FPS
from manimlib.constants import DEFAULT_PIXEL_HEIGHT, DEFAULT_PIXEL_WIDTH from manimlib.constants import DEFAULT_RESOLUTION
from manimlib.constants import FRAME_HEIGHT from manimlib.constants import FRAME_HEIGHT
from manimlib.constants import FRAME_WIDTH from manimlib.constants import FRAME_WIDTH
from manimlib.mobject.mobject import Mobject from manimlib.mobject.mobject import Mobject
@ -29,10 +29,9 @@ class Camera(object):
window: Optional[Window] = None, window: Optional[Window] = None,
background_image: Optional[str] = None, background_image: Optional[str] = None,
frame_config: dict = dict(), frame_config: dict = dict(),
pixel_width: int = DEFAULT_PIXEL_WIDTH, # Note: frame height and width will be resized to match this resolution aspect ratio
pixel_height: int = DEFAULT_PIXEL_HEIGHT, resolution=DEFAULT_RESOLUTION,
fps: int = DEFAULT_FPS, fps: int = DEFAULT_FPS,
# Note: frame height and width will be resized to match the pixel aspect ratio
background_color: ManimColor = BLACK, background_color: ManimColor = BLACK,
background_opacity: float = 1.0, background_opacity: float = 1.0,
# Points in vectorized mobjects with norm greater # Points in vectorized mobjects with norm greater
@ -47,9 +46,9 @@ class Camera(object):
# to set samples to be greater than 0. # to set samples to be greater than 0.
samples: int = 0, samples: int = 0,
): ):
self.background_image = background_image
self.window = window self.window = window
self.default_pixel_shape = (pixel_width, pixel_height) self.background_image = background_image
self.default_pixel_shape = resolution # Rename?
self.fps = fps self.fps = fps
self.max_allowable_norm = max_allowable_norm self.max_allowable_norm = max_allowable_norm
self.image_mode = image_mode self.image_mode = image_mode

View file

@ -7,6 +7,7 @@ import inspect
import os import os
import sys import sys
import yaml import yaml
from ast import literal_eval
from functools import lru_cache from functools import lru_cache
@ -292,22 +293,24 @@ def get_resolution(args: Optional[Namespace] = None, global_config: Optional[dic
args = args or parse_cli() args = args or parse_cli()
global_config = global_config or get_global_config() global_config = global_config or get_global_config()
camera_resolutions = global_config["camera_resolutions"] resolution_options = global_config["resolution_options"]
if args.resolution: if args.resolution:
resolution = args.resolution resolution = tuple(map(int, args.resolution.split("x")))
elif args.low_quality: elif args.low_quality:
resolution = camera_resolutions["low"] resolution = resolution_options["low"]
elif args.medium_quality: elif args.medium_quality:
resolution = camera_resolutions["med"] resolution = resolution_options["med"]
elif args.hd: elif args.hd:
resolution = camera_resolutions["high"] resolution = resolution_options["high"]
elif args.uhd: elif args.uhd:
resolution = camera_resolutions["4k"] resolution = resolution_options["4k"]
else: else:
resolution = camera_resolutions[camera_resolutions["default_resolution"]] resolution = global_config["camera"]["resolution"]
width_str, height_str = resolution.split("x") if isinstance(resolution, str):
return int(width_str), int(height_str) resolution = literal_eval(resolution)
return resolution
def get_window_config(args: Namespace, global_config: dict) -> dict: def get_window_config(args: Namespace, global_config: dict) -> dict:
@ -315,7 +318,7 @@ def get_window_config(args: Namespace, global_config: dict) -> dict:
# Todo, this correction of configuration should maybe happen elsewhere # Todo, this correction of configuration should maybe happen elsewhere
for key in "position", "size": for key in "position", "size":
if window_config.get(key): if window_config.get(key):
window_config[key] = eval(window_config[key]) window_config[key] = literal_eval(window_config[key])
if args.full_screen: if args.full_screen:
window_config["full_screen"] = True window_config["full_screen"] = True
return window_config return window_config
@ -325,27 +328,21 @@ def get_camera_config(args: Optional[Namespace] = None, global_config: Optional[
args = args or parse_cli() args = args or parse_cli()
global_config = global_config or get_global_config() global_config = global_config or get_global_config()
width, height = get_resolution(args, global_config) camera_config = global_config["camera"]
fps = int(args.fps or global_config["fps"])
camera_config = {
"pixel_width": width,
"pixel_height": height,
"fps": fps,
}
# All of this should be taken care of during some initialization of global_config
camera_config["resolution"] = get_resolution(args, global_config)
if args.fps:
camera_config["fps"] = args.fps
if args.color:
try: try:
bg_color = args.color or global_config["style"]["background_color"] camera_config["background_color"] = colour.Color(args.color)
camera_config["background_color"] = colour.Color(bg_color) except Exception:
except ValueError as err:
log.error("Please use a valid color") log.error("Please use a valid color")
log.error(err) log.error(err)
sys.exit(2) sys.exit(2)
# If rendering a transparent image/movie, make sure the
# scene has a background opacity of 0
if args.transparent: if args.transparent:
camera_config["background_opacity"] = 0 camera_config["background_opacity"] = 0.0
return camera_config return camera_config

View file

@ -36,6 +36,11 @@ window:
# Other optional specifications that override the above # Other optional specifications that override the above
# position: (500, 500) # Specific position, in pixel coordiantes, for upper right corner # position: (500, 500) # Specific position, in pixel coordiantes, for upper right corner
# size: (1920, 1080) # Specific size, in pixels # size: (1920, 1080) # Specific size, in pixels
camera:
resolution: (1920, 1080)
background_color: "#333333"
fps: 30
background_opacity: 1.0
file_writer_config: file_writer_config:
# If break_into_partial_movies is set to True, then many small # If break_into_partial_movies is set to True, then many small
# files will be written corresponding to each Scene.play and # files will be written corresponding to each Scene.play and
@ -52,14 +57,11 @@ style:
tex_template: "default" tex_template: "default"
font: "Consolas" font: "Consolas"
text_alignment: "LEFT" text_alignment: "LEFT"
background_color: "#333333" resolution_options:
camera_resolutions: low: (854, 480)
low: "854x480" med: (1280, 720)
med: "1280x720" high: (1920, 1080)
high: "1920x1080" 4k: (3840, 2160)
4k: "3840x2160"
default_resolution: "high"
fps: 30
universal_import_line: "from manimlib import *" universal_import_line: "from manimlib import *"
embed_exception_mode: "Verbose" embed_exception_mode: "Verbose"
embed_error_sound: False embed_error_sound: False

View file

@ -411,7 +411,7 @@ class VShaderWrapper(ShaderWrapper):
along with the rgb value which is meant to be discarded. along with the rgb value which is meant to be discarded.
""" """
cam_config = get_camera_config() cam_config = get_camera_config()
size = (cam_config['pixel_width'], cam_config['pixel_height']) size = cam_config["resolution"]
double_size = (2 * size[0], 2 * size[1]) double_size = (2 * size[0], 2 * size[1])
# Important to make sure dtype is floating point (not fixed point) # Important to make sure dtype is floating point (not fixed point)