Nodes/Symbiotica/Control Image
ComfyUI Node

Control Image

Load Image, Except Every ControlNet File Is Already in the List

By symbiotica-ai·Created 6 months ago·Updated about 12 hours ago· 2
Control Image
    • IMAGE
    • MASK
    image

    What it actually is

    Control Image is core Load Image with one change that turns out to matter more than it sounds: the dropdown does not list your input/ folder, it lists everything under input/controlnet/, subfolders included.

    If you have ever built a ControlNet pipeline, you know the drift. Your edge maps, depth maps, pose skeletons, tile refs and that one painting you condition on are scattered through the same input/ directory as your upscale tests, your masks, and thirty files called ComfyUI_temp_xxxxx.png. You scroll a dropdown of four hundred names and pick blind. Then you open the workflow on the render box and the file isn't there.

    ControlNet is the one part of ComfyUI where the input image carries real information - structure, pose, depth - rather than being a seed for the sampler (controlnet.md). That makes those files worth keeping in one place, and this node is that decision made executable.

    How it works

    The mechanism is almost aggressively simple, which is why it works. On load the node walks input/controlnet/ recursively, skips dotfiles and anything that isn't .png, .jpg, .jpeg or .webp, and sorts what's left by relative path (control_image.py, _control_image.py). Each entry shows as folder/name.png, so input/controlnet/bakery/counter.png appears as bakery/counter.png.

    That relative string is what gets stored in your workflow, not an absolute path. That's the whole point: a workflow, or a recipe that records it, can name a control image without hardcoding where the install lives, and any box that mounts the same library resolves it.

    Then it hands off to core LoadImage().load_image("controlnet/<name>"). So past the dropdown it is Load Image - same decoding, same EXIF rotation, same two outputs.

    Two details worth knowing because they're the kind of thing that saves you an hour:

    • The reload trick is byte-level. IS_CHANGED returns a SHA-256 of the file's contents, not its mtime. Re-export a depth map over the old filename and the node correctly re-runs; leave it alone and the cache holds. Core Load Image does the same; this node just didn't lose it.
    • Paths are constrained. Any value that resolves outside input/controlnet/ is refused by name (is outside controlnet/). Nothing to configure, but it means a hand-edited workflow JSON can't pull a file from somewhere else.

    The input and the outputs

    You set exactly one thing: image, the enum. The author's own tooltip says it best - an image under input/controlnet/, subfolders included, uploaded there from the hub's storage browser, with new files appearing after a browser reload.

    Out come IMAGE and MASK. IMAGE goes where any control image goes: into a preprocessor, or straight into your ControlNet Apply node's image input if your map is already prepared. MASK is the alpha channel inverted, exactly as core Load Image produces it - and if you feed it a JPEG with no alpha, core returns the same 64×64 zero mask it always has. Don't wire that MASK expecting a subject mask; it isn't one.

    Installing it

    The pack installs the usual two ways. Search Symbiotica in ComfyUI Manager, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/symbiotica-ai/comfyui-nodes.git symbiotica
    pip install -r symbiotica/requirements.txt
    

    Then restart ComfyUI and make the library folder, because the node assumes it exists:

    mkdir -p ComfyUI/input/controlnet
    

    Drop your control images in there (subfolders are fine, recursion is real), reload the browser page, and they're all in the dropdown.

    Two honest notes on cost. This node needs nothing - no API key, no model download, no network call. It's pillow, which ComfyUI already ships. But you are installing an all-in-one pack with agents, Wavespeed wrappers, Whisper and Remotion renderers to get one dropdown. The requirements are light (requests, pillow, faster-whisper) and no key is required for the package to load, but faster-whisper downloads weights on first Whisper run, and the caption/overlay nodes want node on your PATH. Put another way: the rest of this pack is API-wrapper territory - the category that has already shipped credential-stealing malware once (external-api-nodes.md) - and this node is the local, boring, read-a-file cousin of all that.

    Where people get stuck

    The dropdown is empty or shows [no images under input/controlnet]. The folder is missing, or your files are in input/ rather than input/controlnet/. Create it and reload.

    You added a file and it isn't listed. The list is built when the node is created, so a new file needs a browser page reload, not just a workflow reload. The tooltip says so plainly.

    Red node after opening a shared workflow. Validation fails by name - no control image 'bakery/counter.png' under input/controlnet rather than core's generic "Invalid image file" - which is genuinely helpful, because it tells you which file to go find. Move the file to the same relative spot and queue again.

    Renamed a file? Re-pick it. The value is a path string; renaming on disk breaks the name, not the cache.

    CategorySymbiotica/Images

    Inputs (1)

    NameTypeDefaultDescription
    imageCOMBOAn image under input/controlnet/, subfolders included. Upload there from the hub's storage browser; new files appear after a browser reload.

    Outputs (2)

    NameTypeDescription
    IMAGEIMAGE
    MASKMASK