Nodes/ComfyUI-Image-Latent-/Image Upload & Latent
ComfyUI Node

Image Upload & Latent

Upload, upscale, and encode in one node — the img2img shortcut that hides a built-in empty latent

By GIlinQ·Created 7 months ago·Updated 7 months ago· 0
Image Upload & Latent
  • vae
  • LATENT
◄image▾►
◄mode▾►
◄upscale_method▾►
◄scale_factor1.0►
◄width512►
◄height512►
◄batch_size1►

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 & Upscale vs Create 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; bicubic is the sane default, lanczos for 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_size goes 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_factor when 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.

Categoryimage/custom

Inputs (8)

NameTypeDefaultDescription
imageCOMBO1 options: example.png
vaeVAE—
modeCOMBO2 options: Upload & Upscale, Create Empty Latent
upscale_methodCOMBO5 options: nearest-exact, bilinear, area, bicubic, lanczos
scale_factorFLOAT1.00.5–8—
widthINT51264–2048—
heightINT51264–2048—
batch_sizeINT11–64—

Outputs (1)

NameTypeDescription
LATENTLATENT—