Image to Base64
Hand a generated image to an LLM as Base64 — the return trip
- image
- base64_string
Base64Decode is the "image comes in from an agent" half of the story. This is the other half: you generated an image, and now software wants it as a string. If you've ever glued ComfyUI's /prompt API to an LLM agent, you know the awkward bit - ComfyUI saves outputs to disk automatically, but "the agent reads a file from the server" is a dance you'd rather not do. Base64Encode turns your IMAGE tensor into a raw Base64 string on the spot, no temp file, no download step. Same pack, same "agent plumbing" philosophy: comfyui-agent-adapter, three tiny nodes, nothing touches the filesystem.
The reason this exists is real. LLM vision APIs (and a whole generation of ComfyUI-agent projects) take images as Base64. The pattern that works - and that the README shows - is: generate → encode → grab the string from the API response → feed it to the agent. This node is the missing tensor → string link in that chain.
How it works
It's a straight tensor-to-string conversion. The node takes the [B, H, W, C] tensor, scales from 0–1 to 0–255, encodes with Pillow into your chosen format, Base64-encodes the bytes, and hands back the string. Two details worth knowing:
- It's marked
OUTPUT_NODE, which means it also surfaces the string in the API result asui.image_base64. So from your script you can readresult["outputs"]["2"]["base64_string"](per the README's example) or grab the UI value - pick whichever your automation prefers. - Only the first image of a batch is encoded. Feed it a 16-frame batch and you'll get frame 0, silently. If you're encoding video frames, this is a trap - encode per frame or don't use this node.
Inputs and outputs that matter
image- required, the tensor you generated.format-PNG(default),JPEG, orWEBP.quality- 1–100, default 95. Here's the thing: quality only applies to JPEG and WEBP. PNG is lossless and ignores it. So don't crank quality down expecting a smaller PNG - it won't change a byte. If size matters and lossy is fine, JPEG or WEBP at ~85 is the sensible pick; PNG is what you want when the bytes need to survive a round-trip intact.
Output is a single base64_string, raw - no data:image/png;base64, prefix. If you're feeding it back into Base64Decode later, no problem: that node strips the prefix anyway. Anything else that wants a data URI will need you to add the prefix yourself.
Where people get burned
The obvious one: a wall of Base64 in your UI is useless to read. The widget is going to show thousands of characters of noise, and nothing in the graph previews the image. This node is for API consumption, full stop. In the browser it's a debugging dead end; in a script it's a gift.
Also note the encode path flattens alpha to RGB for JPEG (JPEG can't do transparency), and grayscale gets repeated to three channels. All standard Pillow behavior, all worth knowing before you wonder why your RGBA result lost its alpha.
Install
Same as its sibling in the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/yaofeng/comfyui-agent-adapter
cd comfyui-agent-adapter
pip install -r requirements.txt
then restart ComfyUI - or search the pack in ComfyUI Manager. Dependencies are Pillow, torch, numpy, all already present in a stock ComfyUI environment, and there are no models to download. It's a one-commit, zero-impressions pack, so treat it as "tiny and does one thing," not "battle-tested." For a node this simple, that's honestly fine.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| formatopt | COMBO | PNG | 3 options: PNG, JPEG, WEBP |
| qualityopt | INT | 951–100 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| base64_string | STRING | — |