Cyberdelia Vision Image Loader
Shrink the photo before your vision model ever sees it
- image
- filename
ComfyUI already has a Load Image node and it works fine. This one exists for exactly one reason: the image-to-prompt path, where a vision-language model reads your picture and writes a caption you'll feed back into a diffusion model. That path sends the image out over the wire as base64, and a modern phone photo is 4000+ pixels on the long edge - a payload nobody wanted and a tensor nobody needed.
Why that matters more than it sounds
Every VLM captioner shares the same blind spot - they're great at describing a scene and unreliable at fine detail, and multi-subject attribution is where they consistently fall over. But the practical limit you hit first is size. The pack's own vision encoder caps the image at 1536 pixels on the longest edge (vision_utils.py, VISION_MAX_DIMENSION) and thumbnails anything bigger before encoding. So if you hand it a 6000px original, the pixels get decoded into a tensor, pushed through the graph, and then thrown away. This loader does the downscale at the front of the graph instead, inside ComfyUI, where it's cheap.
It kills two small annoyances too: a ↻ Refresh images button that re-scans the input folder without a page reload, and a 🗑 Delete selected image button - confirmation dialog included - for the fifth time you've uploaded IMG_2031.jpg by mistake.
Inputs and outputs
Two inputs, per the node's schema:
image- the dropdown plus upload control. Author's tooltip: "Select or upload one image for Prompt Engineer Vision mode." One image, not a batch. It lists what's inComfyUI/input(subfolders included) and it's the only loader in the pack.vision_size-1536 max (recommended)(default),1024 max,768 max,512 max, ororiginal. The tooltip is straight about it: "Downscale the longest edge without cropping or upscaling. 1536 matches Prompt Engineer's internal Vision limit."
Outputs:
image(IMAGE) - wire it to the Prompt Engineer node'simageinput. Standard ComfyUI tensor,[1,H,W,3].filename(STRING) - the path relative to the input folder. Handy for a note node or for stashing the source name in metadata, since vision captions otherwise lose all trace of which file produced them.
How it behaves under the hood
The resize is proportional and downscale-only: if the image is already at or under the limit it is passed through untouched, no resampling artifact at all. When it does resize, it uses Lanczos, EXIF rotation is applied first (so a portrait phone shot isn't lying on its side by the time the model sees it), and the result is converted to RGB - alpha gets dropped, which is exactly what you'd want before a base64 encode anyway. Animated formats load their first frame only, matching how the engineer node reads an image batch.
Paths are sandboxed: absolute paths, anything outside the input directory, and non-image extensions are refused with a clear validation error rather than a stack trace. And IS_CHANGED hashes the file contents plus the chosen vision_size, which is the nice, quiet bit - overwrite ref.png with a different image and the next queue actually re-runs instead of serving you the cached tensor of the old one.
Install it
Manager, search Cyberdelia, or:
cd ComfyUI/custom_nodes
git clone https://github.com/cyberdeliaAI/comfyui-cyberdelia-z-engineer.git
pip install -r comfyui-cyberdelia-z-engineer/requirements.txt
Restart after. The pack's only declared dependency is requests; Pillow and PyTorch are already in ComfyUI. No model downloads, no server needed for this node - the LLM endpoint only matters once you enable Vision on the Prompt Engineer node itself, which is where you also need a model the server reports as vision-capable (auto will only pick from those).
Sizing advice, and the traps
Don't set original "to be safe." You'll get the full-size tensor through your graph and then the engineer node will thumbnail it to 1536 anyway. All you bought was VRAM and a slower queue.
1536 is the pack's number, not the model's. It's a sane default that matches the internal cap, so it's the one setting where you lose nothing. Dropping to 768 or 512 is the real lever when vision requests feel slow or memory gets tight - the cost is fine detail: small text, texture, jewellery, anything that lives in single pixels. Describing a photo for img2img, 768 is usually plenty. Reading a screenshot or matching an outfit precisely, keep 1536.
A vague caption is often the loader's fault. At 512 you've deleted the detail the model would have described, and no prompt wording gets it back.
The delete button can't reach your outputs. It only unlinks the explicitly selected file inside the input folder, with a confirm dialog; output and temp files, arbitrary paths, or the whole list are out of scope by design.
Refresh buttons are frontend helpers. They call the pack's /cyberdelia/z-engineer/input-images routes. If the JS didn't load you'll get a browser alert instead of a refreshed list, and the plain combo box is still there underneath - new files show up once ComfyUI re-reads the folder.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | COMBO | Select or upload one image for Prompt Engineer Vision mode. | |
| vision_size | COMBO | 1536 max (recommended) | Downscale the longest edge without cropping or upscaling. 1536 matches Prompt Engineer's internal Vision limit. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| filename | STRING | — |