Nodes/Basic data handling/save IMAGE+MASK to file
ComfyUI Node

save IMAGE+MASK to file

Save a cutout with its mask baked into the alpha channel

By StableLlama·Created about a year ago·Updated 4 days ago· 48
save IMAGE+MASK to file
  • images
  • mask
  • success
path
formatpng
quality95
invert_maskfalse
create_dirstrue

Every background-removal workflow ends the same way: you've got a foreground cut out and a mask, and you want a PNG you can drop into Photoshop, an HTML mockup, or a game. ComfyUI's built-in Save Image won't do it - it writes the RGB image and throws the mask away. That's the gap this node fills. It takes an IMAGE and a MASK and writes one RGBA file where the mask becomes the alpha channel, so transparent pixels stay transparent everywhere downstream.

How it works

Under the hood it's plain Pillow: the node takes the first image in your batch, multiplies the tensor by 255 to get a normal image, builds a single-channel "L" mask image from your mask tensor, and calls putalpha() to glue them into an RGBA frame before saving. The one subtlety is direction. ComfyUI masks are conventionally 1.0 = "keep", 0.0 = "erase", but a PNG alpha channel is the opposite - 255 alpha is fully opaque. So the node inverts internally: alpha = 255 * (1.0 - mask). That's also why the invert_mask toggle exists: if your mask was built the other way round (or you just want transparent where the mask says solid), flip it and the math goes the other way.

A couple of format guardrails are baked in. JPEG doesn't support transparency, so if you ask for jpg it quietly downgrades to PNG rather than producing garbage. WebP works and keeps alpha; JXL works too but only if you've installed pillow-jxl-plugin yourself - the pack won't do it for you.

The inputs that matter

  • images - your foreground tensor.
  • mask - the selection, same size, 0–1 float.
  • path - where to write it. Empty path = silent failure (returns False), so this is the one to get right.
  • format (default png), quality (default 95), invert_mask (default off), create_dirs (default on).

The single output, success, is a BOOLEAN. It's an output node, so nothing downstream needs it, but you can wire it into a STRING-style assertion or a flow-control check if you want the workflow to stop when the save actually failed.

Installing it

This is part of the Basic data handling pack by StableLlama, a "Python stdlib as nodes" toolkit. Install it once and you get all ~200 nodes, including this one:

cd ComfyUI/custom_nodes
git clone https://github.com/StableLlama/ComfyUI-basic_data_handling

Then restart ComfyUI. Or just open ComfyUI Manager, search "Basic data handling", and hit install. The notable thing here: the pack's pyproject.toml declares zero dependencies. No requirements.txt, no model downloads, nothing to conflict with your other nodes - a real rarity in a scene where every pack drags in its own torch-era dependency. If you want JXL, that's the only optional add-on, and it's on you.

Gotchas

  • Only the first image of a batch is written. Feed a batch of 4 and you get one PNG, silently. If you need each frame saved, loop the workflow per image instead.
  • Your path gets .png appended only if it doesn't already end in the right extension.
  • The node logs failures to the console (Basic data handling: Error saving image...) rather than raising, so a bad directory or a typo'd path shows up as success = False, not as a red error. Check the terminal when saves mysteriously do nothing.
CategoryBasic/Path

Inputs (7)

NameTypeDefaultDescription
imagesIMAGE
maskMASK
pathSTRING
formatoptSTRINGpng
qualityoptINT951–100
invert_maskoptBOOLEANfalse
create_dirsoptBOOLEANtrue

Outputs (1)

NameTypeDescription
successBOOLEAN