Superside White Balance
Superside White Balance
- image
- image
Run an image through a generative editor a few times and it starts to go warm. Each Nano Banana or GPT-Image pass adds a tiny color bias, it compounds, and before long your clean white background reads beige and skin has a sunset tint. The instinct is to throw the image back through another model to "fix" it - which adds another pass of drift and costs money. The right move is this node, which is a plain, deterministic white-balance operation: no API call, no model, no key. Milliseconds, free, and exactly the "don't burn a diffusion pass on work a lookup table does perfectly" lesson in one place.
How it works
White balance is per-channel gain. The node picks a neutral reference - a region you say should be white - measures its average RGB, and rescales each channel so that reference reads neutral. Because it scales to the reference's own brightness rather than forcing it to pure white, overall exposure is preserved; a "white" patch that's slightly gray in the source stays that bright, it just loses the color. You pick the reference three ways:
manual_sample(default): pointsample_x/sample_yat a spot you know should be white. The defaultsample_yof 0.08 aims near the top of the frame - where a catalogue's white backdrop usually lives. This is the reliable one; the README says so outright.auto_white_patch: treats the brightest pixels (topauto_percentile%, default 95) as the white reference. Good when there's a genuine bright patch; less good when the brightest thing in frame is a lit candle.gray_world: assumes the whole image averages to neutral gray. Fine for mixed scenes, wrong for a beach or a red room.
strength (0–1) blends between untouched and full correction - handy when the fix overshoots, like a portrait whose hair was supposed to be warm. preserve_luminance (on by default) rescales so brightness stays put and only the cast moves; turn it off to push the reference all the way to pure white instead.
Inputs and output
Required: image, mode. Optional: sample_x, sample_y, sample_size (the patch is a square as a fraction of the shorter side), auto_percentile, strength, preserve_luminance. One output: image (IMAGE), same size, alpha preserved. Drop it anywhere a normal image goes.
Installing
It's part of the Superside pack, so it's the same install as its API-calling siblings - only this one is one of the "no API key needed" utilities:
cd ComfyUI/custom_nodes
git clone https://github.com/Superside/comfyui-superside-nodes.git
pip install -r requirements.txt
restart, then find it under Superside in the node menu. ComfyUI Manager works too. There's no model, no key, no network - the whole node is a few dozen lines of numpy.
Troubleshooting
- Warm cast still there → your sample patch wasn't neutral. Pick a region you're certain should be white or gray - a specular highlight, a white shirt, the background. Sampling the skin will "neutralize" to skin tone and shift everything weird.
- Correction looks wrong on the subject → back
strengthoff to 0.3–0.6. The reference tells you what white is; it doesn't tell you the subject was supposed to stay slightly warm. gray_worldandauto_white_patchboth miss → go manual. It's the default mode for a reason.
If your drift comes from an iterative-edit pipeline (Nano Banana Pro/V2 chain), the fix belongs at the end of the chain, not between every pass - one correction on the final output is usually enough.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mode | COMBO | manual_sample | 3 options: manual_sample, auto_white_patch, gray_world |
| sample_xopt | FLOAT | 0.500–1 | manual_sample: horizontal center of the white reference patch (0 = left, 1 = right). |
| sample_yopt | FLOAT | 0.080–1 | manual_sample: vertical center of the white reference patch (0 = top, 1 = bottom). A corner/background is usually safest. |
| sample_sizeopt | FLOAT | 0.100.01–1 | manual_sample: size of the square reference patch, as a fraction of the shorter side. |
| auto_percentileopt | FLOAT | 95.050–100 | auto_white_patch: pixels brighter than this luminance percentile are treated as the white reference. |
| strengthopt | FLOAT | 1.000–1 | How much of the correction to apply. 1.0 = full neutralization, 0.5 = halfway. |
| preserve_luminanceopt | BOOLEAN | true | Scale the correction so overall brightness stays the same (only the color cast changes). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |