RGBA Safe Post (Swwan)
How to get your colors back after RGB-only nodes wreck your alpha
- image
- alpha
- image_out
- alpha_out
RGBA_Safe_Post is the "undo" half of the pack's premultiply trick. RGBA_Safe_Pre multiplied your RGB by alpha so transparent pixels became black and stopped bleeding fringes into your image. The moment you're done processing, though, that premultiplied RGB is wrong - colors get darker toward the edges, and a saved PNG looks muddy. Post un-premultiplies it, safely, and hands you back straight color plus an alpha that matches your new image size.
You reach for it the moment you need the corrected tensors to continue into more nodes instead of going straight to a save. The pack's RGBA_Multi_Save does this same logic internally on its transparent-output path, but it can't hand you tensors - Post can.
How it works
The mechanism is the whole reason this node exists. Unpremultiplying means dividing RGB by alpha. That's mathematically fine where alpha is 1, and quietly catastrophic where alpha is near zero: dividing a pixel's color by ~0 gives you a blindingly bright speck, and at exactly 0 you divide by zero. The source handles it with two moves:
- An
epsilonfloor: alpha is clamped to at leastepsilonbefore the division. - A hard rule: pixels whose alpha is below
epsiloncome out as black (they're fully transparent anyway - their color is gone and was never going to be seen).
The node also resizes your original alpha to match the processed image's dimensions (bicubic), because any RGB-only node that changed the image size left your alpha at the wrong resolution.
Inputs and outputs
image(IMAGE) - the processed, still-premultiplied RGB from your RGB-only nodes.alpha(MASK) - the alpha thatRGBA_Safe_Pregave you.has_alpha(BOOLEAN) - that same node's boolean. When it'sFalse, Post is a pure passthrough.epsilon(FLOAT, default0.001, range1e-6to0.1) - the minimum alpha floor. Leave it at the default; the tooltip is the whole story: it avoids divide-by-zero and bright edge artifacts.
Outputs:
image_out(IMAGE) - corrected, straight (unpremultiplied) RGB.alpha_out(MASK) - the resized alpha, ready to wire intoRGBA_Saveor anything else that needs a mask at the current size.
The recommended flow
Load Image → RGBA Safe Pre → (any RGB-only nodes) → RGBA Safe Post → more nodes / RGBA Save
Wire image_out and alpha_out from Post into whatever's next, and for a final PNG use RGBA_Save with Post's image_out and alpha_out. That's the pipeline where Post earns its keep - you get to keep working on a correct image instead of being forced to save at the moment of repair.
Install
In the ComfyUI_Swwan pack. ComfyUI Manager → search "ComfyUI_Swwan", or:
cd ComfyUI/custom_nodes
git clone https://github.com/aining2022/ComfyUI_Swwan
cd ComfyUI_Swwan
pip install -r requirements.txt
Restart, then grab it from Swwan/RGBA.
The traps
Don't unpremultiply twice. If you run RGBA_Safe_Post on an image that's already straight, you're dividing by alpha again and you'll get the same edge artifacts you were fixing. The tooltip on RGBA_Save says it plainly: use Post first if the image is still premultiplied - check that before you build the habit.
Second, remember unpremultiply is lossy at fully transparent pixels. Those colors were multiplied to black in Pre and can't be recovered; Post returns them as black, which is fine because they're invisible. If your workflow ever needs the true edge color back (say, for compositing against a bright background), premultiplying in the first place was the wrong choice - that's an edge case, not a bug.
Third, has_alpha must come from the same Pre that produced your alpha. Mix a has_alpha from one branch with an alpha from another and the passthrough logic will silently do the wrong thing. Keep the three outputs of Pre together as a bundle.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Processed IMAGE output, usually after passing through RGB-only nodes. | |
| alpha | MASK | Original alpha returned by RGBA Safe Pre. | |
| has_alpha | BOOLEAN | Boolean flag returned by RGBA Safe Pre. False makes this node act as passthrough. | |
| epsilon | FLOAT | 0.00100.000001–0.1 | Minimum alpha used during unpremultiply to avoid divide-by-zero and bright edge artifacts. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image_out | IMAGE | — |
| alpha_out | MASK | — |