ComfyUI Node

Image Prep

How to get a ComfyUI image into a vision LLM

By ComfyUI-Kelin·Created 2 years ago·Updated 4 months ago· 27
Image Prep
  • image
  • image_2
  • image_3
  • image_4
  • image_5
  • image_6
  • image_7
  • image_8
  • processed_image
â—„formatPNGâ–ş
â—„qualityHighâ–ş

Vision LLMs don't eat tensors - this is the translator

You've built a nice ComfyUI graph, you've got an output image, and now you want to send it to a multimodal LLM - caption it, ask it to critique the composition, have Qwen-VL describe what's wrong so you can fix the prompt. One problem: ComfyUI hands you a raw image tensor, and every LLM API on earth expects base64. That gap is what Image Prep exists to close. It converts one or more ComfyUI images into base64 data-URIs and hands them to the OpenAI Compatible Adapter's prep_img input, which is the pack's vision pipeline in a single wire.

The name is a mild lie - it doesn't resize to a fixed size or prep in the "make this look good" sense. What it does is format conversion: tensor → PIL → compressed bytes → base64 → a JSON array of data URLs. If you've ever hand-built that with a custom Python node, you'll recognize the whole job.

How it works

Each image input slot gets encoded to a PIL image, optionally downscaled, and base64-encoded into a data:image/<format>;base64,<bytes> string. The output (processed_image, a STRING) is the JSON array of all those data URLs - that array is exactly what the adapter's prep_img field parses and stuffs into the API's image_url message format. Only connected slots are processed, so an empty image_4 slot costs you nothing.

The two dropdowns control size and compression:

  • format - PNG, JPEG, WebP, GIF, BMP, or TIFF. For vision APIs, JPEG or WebP is the pragmatic default; PNG is safest but fattest.
  • quality - High/Medium/Low. This is the sleeper setting. It doesn't just map to JPEG compression (95/75/50); it also caps the longest edge at 1024px (High), 768px (Medium), or 512px (Low) before encoding. Your API bill is proportional to how many tokens an image costs, and smaller images cost fewer - so if you're captioning in bulk, Low can cut both payload and cost dramatically.

It handles up to eight images: the required image slot plus image_2 through image_8. A batch tensor with multiple frames gets split into one data URI per frame.

Wiring it up

Load your image (any loader), feed the IMAGE output into image, then connect processed_image to the OpenAI Compatible Adapter's prep_img input. Pick a multimodal model in the adapter (Qwen-VL, GLM-4V, GPT-4o, or any vision-capable OpenAI-compatible model) and prompt away. Plain text models will simply ignore the image.

Installing

Part of the HuangYuChuh/ComfyUI-LLMs-Toolkit pack, so it installs with everything else. ComfyUI Manager → search ComfyUI-LLMs-Toolkit → Install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/HuangYuChuh/ComfyUI-LLMs-Toolkit
cd ComfyUI-LLMs-Toolkit
pip install -r requirements.txt

Dependencies are light (Pillow + aiohttp) - Pillow is doing all the real work here, and no models are downloaded.

Gotchas

The classic mistake is expecting this node to shrink a 1024Ă—1024 image to a thumbnail - it doesn't touch images smaller than the quality cap, so at High a small image stays as-is. The other trap is feeding the output into a node that isn't the adapter's prep_img: the output is a string of a JSON array, not an image, so anything expecting an IMAGE type will throw a type error. And for the biggest gotcha - enormous images producing huge base64 blobs and API 413 errors - the pack's own error message sums it up: "Compress images to <1024x1024, or reduce quality." Drop the quality to Medium or Low before you blame the provider.

Category🚦ComfyUI_LLMs_Toolkit/Image

Inputs (10)

NameTypeDefaultDescription
imageIMAGE—
formatoptCOMBOPNG6 options: PNG, JPEG, WebP, GIF, BMP, TIFF
qualityoptCOMBOHigh3 options: High, Medium, Low
image_2optIMAGE—
image_3optIMAGE—
image_4optIMAGE—
image_5optIMAGE—
image_6optIMAGE—
image_7optIMAGE—
image_8optIMAGE—

Outputs (1)

NameTypeDescription
processed_imageSTRING—