ntl Load Images (Base64)
Push Base64 Images Into ComfyUI as a Batch — No File, No Upload
- IMAGE
The display name - "ntl Load Images (Base64)" - is accurate but undersells it. This node takes a JSON list of base64-encoded images and hands you back a proper batched IMAGE tensor, ready to feed the rest of your graph. You're not going to reach for it by hand. You reach for it when your ComfyUI workflow is being driven by something else: a plugin, a web app, a Python script that already has images in memory as base64 and wants them in the graph without writing files or hitting an upload endpoint.
That's the whole job of the "external_tooling" category this pack sits in. ComfyUI is usually file-shaped - you Save Image to disk, you Load Image from disk - but it's also a backend you can drive purely from code. Submit a workflow through the API and you hand it a prompt JSON; if one of your inputs is already base64 (which is how images travel through most web APIs and plugins anyway), this node is the seam where that string becomes a tensor. It's a rewrite of Acly's External Tooling Nodes (ETN_LoadImageBase64), with one real upgrade: it accepts an array, so a client can push a whole batch in a single message instead of one image at a time. The pack README is basically a memo about this pipeline - this is the receiving half of base64-over-websocket.
How it works
The mechanism is boring in the best way. Each string in the array gets base64-decoded, opened with PIL, converted to RGB, scaled from 0–255 to float 0–1, and turned into a torch tensor. Then everything is stacked along the batch dimension. One JSON payload in, one [N, H, W, 3] IMAGE out.
The inputs that matter
There's exactly one input, and you'll set it almost never by typing:
- images (STRING): a JSON array of base64 strings, like
["aGVsbG8=", "..."]. The field is single-line and the payload is huge, so the realistic path is that your external client injects it into the workflow JSON it builds - the same way the README's example drives the send side.
The single output is IMAGE, batched. Wire it into a VAE decode, an img2img sampler, whatever node normally eats an image.
Where people get burned
The traps are all in how the code stacks the batch:
- Mixed image sizes crash it. Every element must be the same pixel dimensions, because the node does a hard
torch.catacross the batch. One 512x512 and one 1024x1024 in the same array = runtime error, not a resize. - It must be valid JSON. A single unquoted blob, a trailing comma, or base64 that isn't actually an image all throw immediately.
- An empty array
[]breaks it - there's nothing to stack, sotorch.catexplodes. Always send at least one image. - Alpha gets discarded. Everything is forced through
convert("RGB"), so PNG transparency doesn't survive. If you're shipping masks, that's gone.
Install
It ships in the tiny LyazS/comfyui-nettools pack ("net tool node for comfyui"). In ComfyUI Manager, search "net tool node for comfyui" and install, or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/LyazS/comfyui-nettools
Then restart ComfyUI. There's no requirements.txt - the node only uses Python's stdlib (base64, json) plus PIL, numpy, and torch, which ComfyUI already ships. No models to download, no API keys. It's a single-file pack (everything lives in __init__.py, one commit from a single author), so if you're the paranoid sort, reading it takes about five minutes - and there's nothing sketchy in there, just base64 and tensors.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| images | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |