Image Upload & Latent
Upload, upscale, and encode in one node — the img2img shortcut that hides a built-in empty latent
- vae
- LATENT
Here's the honest pitch for Image Upload & Latent: it's three nodes ComfyUI already ships, stapled into one. Upload an image, upscale it, run it through your VAE, and get a LATENT out - or flip a switch and get a blank latent instead. Nothing in here is magic, and nothing here needs an extra download. What it buys you is a cleaner graph when you're doing img2img, which is exactly the workflow where you'd otherwise be dragging Load Image → UpscaleImage → VAEEncode around and wondering why your canvas is full.
The node lives in the tiny GIlinQ/ComfyUI-Image-Latent- pack, and it's the only node in it. The whole thing is one Python file with zero extra dependencies - torch, numpy, and Pillow, all of which ComfyUI already has. That's rarer than it should be in this ecosystem.
How it works
A mode dropdown decides which of the two halves runs. Pick Upload & Upscale and the node grabs your image from ComfyUI's input folder, checks it's under 20 MB, fixes EXIF orientation, and loads it as a (B, H, W, C) tensor in [0, 1]. If scale_factor isn't 1.0, it rescales the pixels - then runs vae.encode() and hands you a LATENT ready to feed a KSampler.
Worth knowing about the upscale part, because it's where the author's implementation shows: four of the five methods (nearest-exact, bilinear, area, bicubic) go through torch.nn.functional.interpolate, but lanczos is routed to PIL's Image.LANCZOS instead. So the "best" method is also the one taking a slightly different code path - fine in practice, but if you're A/B testing methods, know they aren't all using the same backend. And note this is a pixel-space upscale before encoding, not a latent-space hires-fix. It adds pixels, not detail - the "more pixels" job, in the upscaling sense, not the "more detail" one. If your source is soft, an ESRGAN model or a second low-denoise pass still beats this.
Switch to Create Empty Latent and it ignores your image entirely and builds torch.zeros([batch_size, 4, h // 8, w // 8]) - the standard SD/SDXL latent shape, 8x downsampled, 4 channels. That's literally the built-in EmptyLatentImage node in disguise.
The inputs that actually matter
- vae - plug in a
Load VAE(or your checkpoint's baked one). You can't skip it even in empty-latent mode; it's a required input. - mode -
Upload & UpscalevsCreate Empty Latent. This is the whole personality of the node. - scale_factor - 0.5 to 8.0, step 0.1, default 1.0 (which means "don't touch"). This is the value you'll actually fiddle with.
- upscale_method - the five listed above;
bicubicis the sane default,lanczosfor quality if you don't mind the PIL path. - width / height / batch_size - only read in empty-latent mode. Width/height step in 64s from 64 to 2048;
batch_sizegoes up to 64, and yes, it only applies to the empty-latent path.
The single output is LATENT, which wires straight into KSampler (use denoise under 1.0 for img2img). That's the whole point - one wire into the sampler instead of a three-node chain.
Installing it
ComfyUI Manager can find it by searching the pack title, or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/GIlinQ/ComfyUI-Image-Latent-
Then restart ComfyUI. No model files, no requirements to install - the requirements.txt is a comment. Find it in the UI under right-click → image → custom → Image Upload & Latent. (The README's own install snippet uses a placeholder repo URL, which is a tell that this is a small, lightly-maintained project - expect it to be this version and nothing more.)
Gotchas
- The image input is required even in empty-latent mode. You'll still see the file picker; whatever you choose is silently ignored. Pick any file and move on.
- Files over 20 MB throw a hard
ValueError. Weirdly strict for local usage, but it's in the code. - This is an SD/SDXL-shaped node. It assumes a 4-channel, 8x VAE. Flux's VAE is 16 channels, so don't point it at a Flux pipeline.
- Watch the
scale_factorwhen you just wanted to encode: at 1.0 it skips the upscale branch, which is what you want for a straight encode.
It's a niche convenience, not a workflow revolution - but if you do a lot of img2img and you're tired of the same three nodes showing up in every graph, this collapses them into one box. That's a reasonable trade.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | COMBO | 1 options: example.png | |
| vae | VAE | — | |
| mode | COMBO | 2 options: Upload & Upscale, Create Empty Latent | |
| upscale_method | COMBO | 5 options: nearest-exact, bilinear, area, bicubic, lanczos | |
| scale_factor | FLOAT | 1.00.5–8 | — |
| width | INT | 51264–2048 | — |
| height | INT | 51264–2048 | — |
| batch_size | INT | 11–64 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |