ImageCounterNode
A frame counter that resets itself, for when loops lie to you
- images
- IMAGE
Here's a genre of bug that only exists in graph editors. You build a loop, you queue it, and 400 images come out with filenames that don't match the settings that produced them. Which grid cell is this? Third row or fourth? The counter you built inside the graph says 12 and the folder says 13 and you have no idea which one drifted.
ImageCounterNode is a debugging node for exactly that. It carries an IMAGE through untouched, prints a running frame number to the console, and - this is the part that matters - resets to zero when a new run starts.
How it works
The mechanism is a class-level counter plus ComfyUI's own queue. On every execution it asks the server for the currently-running prompt id, and if that id differs from the one it saw last, it zeroes the count and prints a reset line. Then it adds the size of the incoming batch and logs:
======================================
[XYZ Plot] Frame #: 12
======================================
Then it returns the same image tensor it received.
batch_size = images.shape[0]
ImageCounterNode.global_image_count += batch_size
...
return (images,)
Two details fall out of that code and both are worth knowing before you use it:
It counts images, not executions. Feed it a batch of four and the number jumps by four. That's correct for "which frame of the grid am I on" and wrong if you were expecting one increment per node visit.
The reset depends on reading the queue. global_image_count and last_prompt_id are stored on the class, not per node instance, and the reset only fires when a prompt id can be read from the running queue. So a fresh queue = a fresh count, and that's the feature: no state carried between runs, no stale number from a graph you abandoned an hour ago.
The one input and one output
Input images: IMAGE, required. Output IMAGE: the same tensor, unmodified. There are no configuration widgets - no offset, no start-at-N, no label. That is the whole interface.
Because it's a pass-through, wiring it costs nothing in image terms: drop it inline between your sampler and your save node, or between the end of your loop and the grid renderer, and let it count what flows past. It's not an output node, so it only executes if something downstream of it does - chain it in the live path, not off in a dead branch, or you'll get no prints and wonder why.
When it's actually worth a node slot
- Native loop / sweep workflows. ComfyUI's loop nodes iterate, but nothing in the UI tells you which iteration you're watching. The console line does.
- Long overnight queues. If run 37 hangs, the last printed frame number tells you where it hung without opening the output folder.
- Nested loops. This is the case the author calls out in the node's own description: JavaScript-based counters in the frontend can't see inside nested iteration, so they misreport. A counter that lives on the Python side and reads the queue gets it right.
If you're not running loops, you don't need this. It's a diagnostic, not plumbing.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/DemonAlone/DemonAlone-nodes-ComfyUI
cd DemonAlone-nodes-ComfyUI
pip install -r requirements.txt
Or search DemonAlone-nodes-ComfyUI in ComfyUI Manager and restart. No models, no frontend extension - the output is a console print, so watch the terminal ComfyUI was launched from, not the browser.
Things that go wrong
Two counters, one shared number. Both instances increment the same class attribute. Put one at the loop entry and one at the exit and you'll see the number climb twice as fast as the images you're generating. Use one per graph.
The count keeps climbing across runs instead of resetting. That means the node couldn't read a running prompt id from the server queue - it catches the error, prints [ImageCounterNode] Error reading internal server queue, and carries on counting from wherever it was. Check the log for that line; a counter that never resets is a counter you can't trust.
No console output at all. It's a pass-through node, so if it isn't upstream of something that actually executes, it never runs. Confirm it's in the live path from your output node.
The pack didn't load. Standard for this repo: the module-level piexif import in image_utilites.py fails the whole package if requirements.txt never got installed. Run the pip line, restart, and the node appears as ImageCounterNode under utility/logging.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |