ComfyUI Node

Image to Base64

Hand a generated image to an LLM as Base64 — the return trip

By yaofeng·Created 6 months ago·Updated 6 months ago· 0
Image to Base64
  • image
  • base64_string
formatPNG
quality95

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 as ui.image_base64. So from your script you can read result["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, or WEBP.
  • 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.

Categoryagent_adapter

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
formatoptCOMBOPNG3 options: PNG, JPEG, WEBP
qualityoptINT951–100

Outputs (1)

NameTypeDescription
base64_stringSTRING