Files
Steve CastleandClaude Opus 4.6 0881ebe131 Initial commit: ComfyUI Image Cycler node
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>
2026-03-07 14:50:11 -08:00

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",
}