Image PinNode (Embed image b64 to workflow)
Pin an Image Into Your Workflow JSON (Yes, the Whole Image)
- IMAGE
You know the drill: someone shares a workflow, you drag it in, and every Load Image node is empty because the PNG lives in their ComfyUI/input folder, not in the JSON. The Image PinNode from CheNing233's one-node pack exists to kill that pain - it bakes the image itself into the workflow file as a base64 string. Share one JSON, the picture travels with it.
ComfyUI's whole sharing culture runs on the promise that a workflow is portable: the graph gets embedded into output PNG metadata, and dragging an image back reconstructs everything. That promise quietly breaks the moment a workflow depends on an input image, because the built-in Load Image only reads files from your local input directory. ImagePin patches that hole. It's a niche tool, but when you need it, nothing in core ComfyUI does it.
How it works
The heavy lifting is a chunk of frontend JavaScript. When you feed the node an image, the JS draws it onto a canvas, converts it to a data:image/png;base64,... data URL, and stuffs that string into a hidden image_data widget. Save the workflow and the string rides along in the JSON; open the workflow elsewhere and it's still there.
On the Python side, load_image decodes the base64, opens it with PIL, runs exif_transpose (so phone photos stop landing sideways), converts to RGB, and hands you a normal IMAGE tensor. There's a stack-trace trick in the JS that swaps the giant string out for a [IMAGE DATA] placeholder during some UI calls so the frontend doesn't choke - you don't need to care about it, just know the real data survives export.
The inputs that matter
Only two, and one of them you'll never touch:
- image - a dropdown listing every file in your
ComfyUI/inputfolder, plus a special#DECODE_FROM_BASE64entry. Pick a file to pin it. Once the base64 is embedded, this input is basically decorative - the Python code ignores it and always decodesimage_data. - image_data - the hidden base64 string. Leave it alone.
The node's one output is a standard IMAGE, so it slots anywhere a Load Image would: straight into a VAE Encode, a ControlNet preprocessor, an IPAdapter reference, whatever.
There's also a 👉 Compress (Recommended!) 👈 button on the node. It downscales anything over 512px to a max of 512px and re-encodes as WebP at 60% quality, which shrinks the embedded string dramatically. Use it unless you genuinely need the full-res pixels embedded.
Installing it
ComfyUI Manager is the easy route - search "ComfyUI_Image_Pin" and install. Or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/CheNing233/ComfyUI_Image_Pin
Then restart ComfyUI. There's no requirements.txt, no models to download, no API key - the whole pack is one Python file and one JS file that lean on torch/PIL/NumPy ComfyUI already ships. Find it in the node menu under utils, or just search "Image PinNode". The code is partly adapted from ltdrdata's ComfyUI-Inspire-Pack - the same Dr. Lt. Data who wrote ComfyUI Manager - so the lineage is solid even if this author is new to you.
Where people get burned
The tradeoff is size. Base64 inflates binary by about 33%, and that string isn't only in your JSON - if you save the output PNG, ComfyUI embeds the whole workflow (embedded image included) into its metadata. Pin a couple of 4K PNGs and your workflow file and your outputs both balloon. That's the whole reason the Compress button exists; on anything over 512px, hit it.
The other footgun is validation. If image_data is missing or empty, the node fails with image_data is required - which is what happens if you hand-edit the JSON or grab a workflow that was saved mid-edit. Don't strip the string out. And note the dropdown wants the source file present at pin time; after it's embedded, the original file can go - the string is the source of truth.
Worth a look if you share workflows that need reference images, want to hand an artist a gallery of prompt+image pairs, or just like your JSON to carry everything.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | COMBO | 2 options: example.png, #DECODE_FROM_BASE64 | |
| image_data | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |