Custom node that cycles through connected image inputs on each generation, with support for up to 10 images and automatic wrap-around. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
import os
|
|
import json
|
|
|
|
_COUNTER_FILE = os.path.join(os.path.dirname(__file__), "counter.json")
|
|
|
|
|
|
def _load_counter():
|
|
try:
|
|
with open(_COUNTER_FILE, "r") as f:
|
|
return json.load(f).get("index", 0)
|
|
except (FileNotFoundError, json.JSONDecodeError):
|
|
return 0
|
|
|
|
|
|
def _save_counter(index):
|
|
with open(_COUNTER_FILE, "w") as f:
|
|
json.dump({"index": index}, f)
|
|
|
|
|
|
class ImageCycler:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"image_1": ("IMAGE",),
|
|
},
|
|
"optional": {
|
|
"image_2": ("IMAGE",),
|
|
"image_3": ("IMAGE",),
|
|
"image_4": ("IMAGE",),
|
|
"image_5": ("IMAGE",),
|
|
"image_6": ("IMAGE",),
|
|
"image_7": ("IMAGE",),
|
|
"image_8": ("IMAGE",),
|
|
"image_9": ("IMAGE",),
|
|
"image_10": ("IMAGE",),
|
|
"reset": ("BOOLEAN", {"default": False}),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("IMAGE", "INT",)
|
|
RETURN_NAMES = ("image", "current_index",)
|
|
FUNCTION = "cycle"
|
|
CATEGORY = "image"
|
|
DESCRIPTION = "Cycles through connected image inputs on each execution. Outputs the next image in the list each generation."
|
|
|
|
@classmethod
|
|
def IS_CHANGED(s, **kwargs):
|
|
# Always re-execute so the counter advances each generation
|
|
return float("NaN")
|
|
|
|
def cycle(self, image_1, image_2=None, image_3=None, image_4=None,
|
|
image_5=None, image_6=None, image_7=None, image_8=None,
|
|
image_9=None, image_10=None, reset=False):
|
|
images = [img for img in [
|
|
image_1, image_2, image_3, image_4, image_5,
|
|
image_6, image_7, image_8, image_9, image_10,
|
|
] if img is not None]
|
|
|
|
if reset:
|
|
_save_counter(0)
|
|
return (images[0], 0)
|
|
|
|
index = _load_counter()
|
|
index = index % len(images)
|
|
selected = images[index]
|
|
|
|
_save_counter(index + 1)
|
|
return (selected, index)
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"ImageCycler": ImageCycler,
|
|
}
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"ImageCycler": "Image Cycler",
|
|
}
|