From 2008eccd71d3b04dc14437107c5f756949596e33 Mon Sep 17 00:00:00 2001 From: rubz Date: Tue, 30 Jun 2026 00:07:49 +0200 Subject: [PATCH] clean up SmartBatchResize outputs and minor polish - remove filenames and output_paths outputs (not actionable in ComfyUI) - keep images and count - update locales and example workflow to match --- .../smart_batch_resize_demo.json | 95 +++++++++++++++++++ js/smart_batch_resize.js | 12 ++- locales/en/nodeDefs.json | 63 ++++++++++++ smart_batch_resize.py | 19 ++-- smart_prompt_controller.py | 9 +- smart_resize.py | 6 +- 6 files changed, 183 insertions(+), 21 deletions(-) create mode 100644 example_workflows/smart_batch_resize_demo.json create mode 100644 locales/en/nodeDefs.json diff --git a/example_workflows/smart_batch_resize_demo.json b/example_workflows/smart_batch_resize_demo.json new file mode 100644 index 0000000..dd7beea --- /dev/null +++ b/example_workflows/smart_batch_resize_demo.json @@ -0,0 +1,95 @@ +{ + "last_node_id": 4, + "last_link_id": 3, + "nodes": [ + { + "id": 1, + "type": "SmartBatchResize", + "pos": [60, 80], + "size": [340, 366], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [1], + "slot_index": 0 + }, + { + "name": "count", + "type": "INT", + "links": [], + "slot_index": 1 + } + ], + "properties": { + "Node name for S&R": "SmartBatchResize" + }, + "widgets_values": [ + "", + 1024, + 8, + "lanczos", + true, + "", + false, + "resized", + true, + "_" + ] + }, + { + "id": 2, + "type": "PreviewImage", + "pos": [460, 80], + "size": [320, 280], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 1 + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + }, + "widgets_values": [] + }, + { + "id": 3, + "type": "Note", + "pos": [460, 390], + "size": [320, 220], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "Smart Batch Resize — outputs uitleg:\n\nšŸ“· images → PreviewImage of verder bewerken\nšŸ“ filenames → bestandsnamen (zonder pad)\nšŸ“ output_paths → volledige paden op schijf\nšŸ”¢ count → aantal verwerkte afbeeldingen\n\nDe node schrijft sowieso naar schijf.\nDe outputs zijn optioneel aan te sluiten." + }, + "widgets_values": [ + "Smart Batch Resize — outputs uitleg:\n\nšŸ“· images → PreviewImage of verder bewerken\nšŸ“ filenames → bestandsnamen (zonder pad)\nšŸ“ output_paths → volledige paden op schijf\nšŸ”¢ count → aantal verwerkte afbeeldingen\n\nDe node schrijft sowieso naar schijf.\nDe outputs zijn optioneel aan te sluiten." + ] + } + ], + "links": [ + [1, 1, 0, 2, 0, "IMAGE"] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 1, + "offset": [0, 0] + } + }, + "version": 0.4 +} diff --git a/js/smart_batch_resize.js b/js/smart_batch_resize.js index 0512a43..071ea26 100644 --- a/js/smart_batch_resize.js +++ b/js/smart_batch_resize.js @@ -20,10 +20,12 @@ app.registerExtension({ } catch (e) { console.error("[SmartBatchResize] Browse failed:", e); } - }); + }, { serialize: false }); - // Exclude button from serialization (saves undefined placeholder to keep index alignment) - btn.serializeValue = () => undefined; + // Fully exclude from serialization (both save AND load skip it) so it never + // shifts the index of the real widgets. serializeValue=()=>undefined did NOT + // do this — it left a placeholder on save but was skipped on load → drift. + btn.serialize = false; // Move Browse button to right after input_folder (index 1) const folderIdx = node.widgets.indexOf(folderWidget); @@ -57,8 +59,8 @@ app.registerExtension({ return; } } - }); - presetWidget.serializeValue = () => undefined; + }, { serialize: false }); + presetWidget.serialize = false; presetWidget._rects = []; presetWidget.draw = function (ctx, node, widgetWidth, y, height) { diff --git a/locales/en/nodeDefs.json b/locales/en/nodeDefs.json new file mode 100644 index 0000000..f5ba9cd --- /dev/null +++ b/locales/en/nodeDefs.json @@ -0,0 +1,63 @@ +{ + "SmartBatchResize": { + "display_name": "Smart Batch Resize šŸ“", + "inputs": { + "input_folder": { "name": "Input folder" }, + "longest_side": { "name": "Longest side (px)" }, + "multiple_of": { "name": "Round to multiple of" }, + "interpolation": { "name": "Interpolation method" }, + "suffix_resolution": { "name": "Add resolution to filename" }, + "suffix_custom": { "name": "Custom filename suffix" }, + "folder_resolution": { "name": "Create resolution subfolder" }, + "folder_custom": { "name": "Custom output subfolder" }, + "skip_if_exists": { "name": "Skip existing files" }, + "delimiter": { "name": "Filename delimiter" } + }, + "outputs": { + "0": { "name": "Images" }, + "1": { "name": "Count" } + } + }, + "SmartResize": { + "display_name": "Smart Resize šŸ“", + "inputs": { + "image": { "name": "Image" }, + "longest_side": { "name": "Longest side (px)" }, + "multiple_of": { "name": "Round to multiple of" }, + "interpolation": { "name": "Interpolation method" }, + "upscale_if_smaller": { "name": "Upscale if smaller" } + }, + "outputs": { + "0": { "name": "Image" }, + "1": { "name": "Width" }, + "2": { "name": "Height" } + } + }, + "SmartResolutionMultiplier": { + "display_name": "Smart Resolution Multiplier šŸ“", + "inputs": { + "image": { "name": "Image" }, + "multiplier": { "name": "Multiplier" }, + "multiple_of": { "name": "Round to multiple of" } + }, + "outputs": { + "0": { "name": "Width" }, + "1": { "name": "Height" }, + "2": { "name": "Resolution" } + } + }, + "SmartPromptController": { + "display_name": "Smart Prompt Controller šŸŽ›ļø", + "inputs": { + "counter": { "name": "Counter" }, + "prompt_list_1": { "name": "Prompt list 1" }, + "prompt_list_2": { "name": "Prompt list 2" }, + "prompt_list_3": { "name": "Prompt list 3" }, + "prompt_list_4": { "name": "Prompt list 4" } + }, + "outputs": { + "0": { "name": "Prompt" }, + "1": { "name": "List index" } + } + } +} diff --git a/smart_batch_resize.py b/smart_batch_resize.py index 94a678b..9fefc56 100644 --- a/smart_batch_resize.py +++ b/smart_batch_resize.py @@ -52,7 +52,8 @@ class SmartBatchResize: "tooltip": "Snap both dimensions to a multiple of this value. Use 8 for SD/Flux." }), "interpolation": (["lanczos", "bicubic", "bilinear", "nearest"], { - "default": "lanczos" + "default": "lanczos", + "tooltip": "Resampling method. Lanczos is sharpest for downscaling." }), # OUTPUT NAMING @@ -63,7 +64,7 @@ class SmartBatchResize: "suffix_custom": ("STRING", { "default": "", "multiline": False, - "tooltip": "Custom text to add before resolution. Only used when suffix_resolution is on." + "tooltip": "Text added after the filename. E.g. photo → photo_headshot." }), # OUTPUT LOCATION @@ -74,7 +75,7 @@ class SmartBatchResize: "folder_custom": ("STRING", { "default": "resized", "multiline": False, - "tooltip": "Subfolder name. Resolution is appended if folder_resolution is on." + "tooltip": "Subfolder name. Resolution is appended if 'Create resolution subfolder' is on." }), # OPTIONS @@ -90,9 +91,9 @@ class SmartBatchResize: } } - RETURN_TYPES = ("IMAGE", "STRING", "STRING", "INT") - RETURN_NAMES = ("images", "filenames", "output_paths", "count") - OUTPUT_IS_LIST = (True, True, True, False) + RETURN_TYPES = ("IMAGE", "INT") + RETURN_NAMES = ("images", "count") + OUTPUT_IS_LIST = (True, False) FUNCTION = "run" CATEGORY = "CraftKit" OUTPUT_NODE = True @@ -144,7 +145,7 @@ class SmartBatchResize: out_dir.mkdir(parents=True, exist_ok=True) interp = INTERP_MAP[interpolation] - images_out, filenames_out, paths_out = [], [], [] + images_out = [] for f in files: out_name = f"{f.stem}{filename_suffix}{f.suffix.lower()}" @@ -167,13 +168,11 @@ class SmartBatchResize: arr = np.array(img_resized).astype("float32") / 255.0 images_out.append(torch.from_numpy(arr).unsqueeze(0)) - filenames_out.append(out_name) - paths_out.append(str(out_path)) if not images_out: raise ValueError("[SmartBatchResize] No images processed.") - return (images_out, filenames_out, paths_out, len(images_out)) + return (images_out, len(images_out)) NODE_CLASS_MAPPINGS = {"SmartBatchResize": SmartBatchResize} diff --git a/smart_prompt_controller.py b/smart_prompt_controller.py index 362e5d1..f120010 100644 --- a/smart_prompt_controller.py +++ b/smart_prompt_controller.py @@ -16,13 +16,14 @@ class SmartPromptController: "step": 1, "display": "number", "control_after_generate": "increment", + "tooltip": "Current position across all lists. Increments each run.", }), }, "optional": { - "prompt_list_1": ("STRING", {"forceInput": True}), - "prompt_list_2": ("STRING", {"forceInput": True}), - "prompt_list_3": ("STRING", {"forceInput": True}), - "prompt_list_4": ("STRING", {"forceInput": True}), + "prompt_list_1": ("STRING", {"forceInput": True, "tooltip": "Prompt list, one prompt per line."}), + "prompt_list_2": ("STRING", {"forceInput": True, "tooltip": "Optional second prompt list."}), + "prompt_list_3": ("STRING", {"forceInput": True, "tooltip": "Optional third prompt list."}), + "prompt_list_4": ("STRING", {"forceInput": True, "tooltip": "Optional fourth prompt list."}), } } diff --git a/smart_resize.py b/smart_resize.py index 01493f7..011154c 100644 --- a/smart_resize.py +++ b/smart_resize.py @@ -44,10 +44,12 @@ class SmartResize: "default": 8, "min": 1, "max": 64, "step": 1, "tooltip": "Snap both dimensions to a multiple of this value. Use 8 for SD/Flux." }), - "interpolation": (["lanczos", "bicubic", "bilinear", "nearest"],), + "interpolation": (["lanczos", "bicubic", "bilinear", "nearest"], { + "tooltip": "Resampling method. Lanczos is sharpest for downscaling." + }), "upscale_if_smaller": ("BOOLEAN", { "default": False, - "tooltip": "Upscale images that are already smaller than longest_side." + "tooltip": "Also upscale images that are already smaller than the target longest side." }), } }