diff --git a/README.md b/README.md index b9a0ac6..ef9ed9b 100644 --- a/README.md +++ b/README.md @@ -104,14 +104,23 @@ You can run Fragmented from the commandline or scripts. ./Fragmented cmd --shader PATH [--load-image PATH] --shader PATH The path to the shader - --output PATH Where to write the resulting image to + --output PATH Where to write the resulting image to. + In batch mode, this must be a folder. --load-image PATH The path to the image. This will overwrite the - load directive of the shader file (optional) + load directive of the shader file. + Passing a folder activates batch mode. + (optional) ``` You can also run `./Fragmented cmd help` to show the help message. +### Batch Mode + +Since version v8.0, you can pass a directory to `--load-image` and `--output`. This will process all images in the input directory and write the output to the output directory. + +> Note: You *can* use this feature for video frames, but it will take a loooong time. + #### Examples ``` diff --git a/build-template/Containerfile b/build-template/Containerfile index 38d31a7..e47f847 100644 --- a/build-template/Containerfile +++ b/build-template/Containerfile @@ -18,4 +18,4 @@ RUN git clone https://github.com/godotengine/godot.git -b 4.3-stable /godot-src FROM clone-src WORKDIR /godot-src -ENTRYPOINT scons platform=linuxbsd target=template_release lto=full optimize=size disable_3d=yes module_text_server_adv_enabled=no module_text_server_fb_enabled=yes module_basis_universal_enabled=no module_csg_enabled=no module_dds_enabled=no module_enet_enabled=no module_gridmap_enabled=no module_hdr_enabled=no module_jsonrpc_enabled=no module_ktx_enabled=no module_mbedtls_enabled=no module_meshoptimizer_enabled=no module_minimp3_enabled=no module_mobile_vr_enabled=no module_msdfgen_enabled=no module_multiplayer_enabled=no module_navigation_enabled=no module_ogg_enabled=no module_openxr_enabled=no module_raycast_enabled=no module_squish_enabled=no module_svg_enabled=no module_tga_enabled=no module_theora_enabled=no module_tinyexr_enabled=no module_upnp_enabled=no module_vhacd_enabled=no module_vorbis_enabled=no module_webrtc_enabled=no module_websocket_enabled=no module_webxr_enabled=no module_zip_enabled=no arch=x86_64 && strip bin/godot.linuxbsd.template_release.x86_64 +ENTRYPOINT scons platform=linuxbsd target=template_release lto=full optimize=size disable_3d=yes module_text_server_adv_enabled=no module_text_server_fb_enabled=yes module_basis_universal_enabled=no module_csg_enabled=no module_enet_enabled=no module_gridmap_enabled=no module_jsonrpc_enabled=no module_mbedtls_enabled=no module_meshoptimizer_enabled=no module_minimp3_enabled=no module_mobile_vr_enabled=no module_msdfgen_enabled=no module_multiplayer_enabled=no module_navigation_enabled=no module_ogg_enabled=no module_openxr_enabled=no module_raycast_enabled=no module_squish_enabled=no module_theora_enabled=no module_upnp_enabled=no module_vhacd_enabled=no module_vorbis_enabled=no module_webrtc_enabled=no module_websocket_enabled=no module_webxr_enabled=no arch=x86_64 && strip bin/godot.linuxbsd.template_release.x86_64 diff --git a/src/Main.gd b/src/Main.gd index 8e54a86..71e6bd3 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -1,5 +1,9 @@ extends Node +const BATCH_MODE_SUPPORTED_EXTS = [ + ".bmp", ".dds", ".exr", ".hdr", ".jpeg", ".jpg", ".ktx", ".png", ".svg", ".webp" +] + @onready var editor_window = %EditorWindow @onready var ui_container = %UserInterfaceContainer @onready var app_name = ProjectSettings.get_setting("application/config/name") @@ -9,9 +13,12 @@ func show_help(): "Usage:\n\n", "./Fragmented cmd --shader PATH [--load-image PATH]\n\n", " --shader PATH The path to the shader\n", - " --output PATH Where to write the resulting image to\n", + " --output PATH Where to write the resulting image to.\n", + " In batch mode, this must be a folder.\n", " --load-image PATH The path to the image. This will overwrite the\n", - " load directive of the shader file (optional)\n") + " load directive of the shader file.\n", + " Passing a folder activates batch mode.\n", + " (optional)\n") func parse_custom_cmdline(args: PackedStringArray): var kwargs: Dictionary = {"--shader": null, "--output": null, "--load-image": null} @@ -25,32 +32,74 @@ func parse_custom_cmdline(args: PackedStringArray): i += 1 return kwargs +func cli_handle_errors(errors: Array) -> int: + # returns number of errors + var n_errors = errors.size() + if n_errors > 0: + print("One or more errors occurred.") + for e in errors: + printerr(e) + return n_errors + func _ready(): var args = OS.get_cmdline_args() if "cmd" in args: # commandline interface if "help" in args: show_help() get_tree().quit(1) - else: - var kwargs: Dictionary = parse_custom_cmdline(args) - if kwargs["--shader"] == null or kwargs["--output"] == null: - show_help() - get_tree().quit(1) - else: - Filesystem.load_shader(kwargs["--shader"]) - var errors = [] - if kwargs["--load-image"] == null: - errors = await $Compositor.update() - else: - errors = await $Compositor.update(kwargs["--load-image"]) - if errors.size() > 0: - print("One or more errors occurred.") - for e in errors: - printerr(e) + return + var kwargs: Dictionary = parse_custom_cmdline(args) + if kwargs["--shader"] == null or kwargs["--output"] == null: + show_help() + get_tree().quit(1) + return + var batch_mode = false + var load_image_dir: DirAccess + if kwargs["--load-image"] != null: + load_image_dir = DirAccess.open(kwargs["--load-image"]) + if load_image_dir != null: + # batch mode + if DirAccess.open(kwargs["--output"]) == null: + printerr("If --load-image is a directory, --output has to be one too.\n") + show_help() get_tree().quit(1) + return else: - Filesystem.save_result(kwargs["--output"]) - get_tree().quit(0) + batch_mode = true + # + Filesystem.load_shader(kwargs["--shader"]) + # + if batch_mode: + var in_dir_path = load_image_dir.get_current_dir() + var out_dir_path: String = kwargs["--output"].rstrip("/") + for f in load_image_dir.get_files(): + var supported = false + for e in BATCH_MODE_SUPPORTED_EXTS: + if f.ends_with(e): + supported = true + break + if supported: + f = in_dir_path + "/" + f + print(f) + var errors = await $Compositor.update(f) + if cli_handle_errors(errors) == 0: + var filename = out_dir_path + "/" + f.substr(f.rfind("/"), -1) + Filesystem.save_result(filename) + else: + get_tree().quit(1) + return + get_tree().quit(0) + else: + var errors = [] + if kwargs["--load-image"] == null: + errors = await $Compositor.update() + else: + errors = await $Compositor.update(kwargs["--load-image"]) + if cli_handle_errors(errors) == 0: + Filesystem.save_result(kwargs["--output"]) + get_tree().quit(0) + else: + get_tree().quit(1) else: update_title() # position windows