cli: added support for processing whole directories (batch mode) - this implements #40; changed build template to support more image formats

This commit is contained in:
ChaoticByte 2025-01-26 21:38:16 +01:00
parent 40374bd849
commit 7810a1fa83
No known key found for this signature in database
3 changed files with 81 additions and 23 deletions

View file

@ -104,14 +104,23 @@ You can run Fragmented from the commandline or scripts.
./Fragmented cmd --shader PATH [--load-image PATH] ./Fragmented cmd --shader PATH [--load-image PATH]
--shader PATH The path to the shader --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-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. 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 #### Examples
``` ```

View file

@ -18,4 +18,4 @@ RUN git clone https://github.com/godotengine/godot.git -b 4.3-stable /godot-src
FROM clone-src FROM clone-src
WORKDIR /godot-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

View file

@ -1,5 +1,9 @@
extends Node extends Node
const BATCH_MODE_SUPPORTED_EXTS = [
".bmp", ".dds", ".exr", ".hdr", ".jpeg", ".jpg", ".ktx", ".png", ".svg", ".webp"
]
@onready var editor_window = %EditorWindow @onready var editor_window = %EditorWindow
@onready var ui_container = %UserInterfaceContainer @onready var ui_container = %UserInterfaceContainer
@onready var app_name = ProjectSettings.get_setting("application/config/name") @onready var app_name = ProjectSettings.get_setting("application/config/name")
@ -9,9 +13,12 @@ func show_help():
"Usage:\n\n", "Usage:\n\n",
"./Fragmented cmd --shader PATH [--load-image PATH]\n\n", "./Fragmented cmd --shader PATH [--load-image PATH]\n\n",
" --shader PATH The path to the shader\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-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): func parse_custom_cmdline(args: PackedStringArray):
var kwargs: Dictionary = {"--shader": null, "--output": null, "--load-image": null} var kwargs: Dictionary = {"--shader": null, "--output": null, "--load-image": null}
@ -25,32 +32,74 @@ func parse_custom_cmdline(args: PackedStringArray):
i += 1 i += 1
return kwargs 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(): func _ready():
var args = OS.get_cmdline_args() var args = OS.get_cmdline_args()
if "cmd" in args: # commandline interface if "cmd" in args: # commandline interface
if "help" in args: if "help" in args:
show_help() show_help()
get_tree().quit(1) get_tree().quit(1)
else: return
var kwargs: Dictionary = parse_custom_cmdline(args) var kwargs: Dictionary = parse_custom_cmdline(args)
if kwargs["--shader"] == null or kwargs["--output"] == null: if kwargs["--shader"] == null or kwargs["--output"] == null:
show_help() show_help()
get_tree().quit(1) get_tree().quit(1)
else: return
Filesystem.load_shader(kwargs["--shader"]) var batch_mode = false
var errors = [] var load_image_dir: DirAccess
if kwargs["--load-image"] == null: if kwargs["--load-image"] != null:
errors = await $Compositor.update() load_image_dir = DirAccess.open(kwargs["--load-image"])
else: if load_image_dir != null:
errors = await $Compositor.update(kwargs["--load-image"]) # batch mode
if errors.size() > 0: if DirAccess.open(kwargs["--output"]) == null:
print("One or more errors occurred.") printerr("If --load-image is a directory, --output has to be one too.\n")
for e in errors: show_help()
printerr(e)
get_tree().quit(1) get_tree().quit(1)
return
else: else:
Filesystem.save_result(kwargs["--output"]) batch_mode = true
get_tree().quit(0) #
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: else:
update_title() update_title()
# position windows # position windows