🌅Image Contrast
Punch up a flat render in one node — Image Contrast, the other half of the adjustment pair
- image
- IMAGE
Flat, washed-out output is a running complaint in every diffusion forum - most models default to a softer, hazier look than people want. Image Contrast is the dead-simple fix: one input, one factor, one output, done. It's the sibling of Image Brightness in the same pack, and together they cover the two adjustments you'll actually make on every other render.
How it works
PIL's ImageEnhance.Contrast, wrapped into a ComfyUI node. The tensor goes to PIL, gets enhance(contrast_factor) applied, comes back as an IMAGE. Inputs:
image- the IMAGE to adjust.contrast_factor- FLOAT, 0.0 to 2.0, step 0.1, default 1.0. One is the no-op: below 1 flattens the image toward gray, above 1 punches the difference between light and dark. 0 is a flat gray; 2.0 is aggressively crunchy.
Output is a single IMAGE. It's flagged as an output node so you get a canvas preview, but the value still flows onward if you wire it into a save or the next processing step.
When you'd reach for it
Right after a VAE decode that came out hazy, or when a Flux/SDXL render looks underexposed and flat even at a sensible CFG. Slap this at 1.1–1.3 and the image reads cleaner without re-rolling the seed. It's also handy in an img2img chain to re-establish contrast before a detailer pass. It's linear contrast though - if you want proper tonal curves, shadow/highlight control, or filmic contrast, this won't replace a real grading tool. It's the quick knob, not the mixer.
Where people get burned
Same caveat as its brightness sibling: the node round-trips through PIL and force-converts to RGB, so an RGBA image loses its alpha channel. Keep transparent compositing out of this node's path.
There's also a small copy-paste wart in the source worth knowing about: the function is literally named apply_brightness inside the contrast class. It does apply contrast correctly - the implementation matches - but if you ever see a stack trace mentioning apply_brightness while using this node, that's why. Harmless, just messy.
Also, no model: contrast at default 1.0 is a no-op, so a "nothing happened" complaint usually means the factor is still at one. Crank it and watch.
Install
Part of the ComfyUI Production Nodes Pack by Uriel Deveaud (KoreTeknology). Install via ComfyUI Manager (search "ComfyUI Production Nodes Pack") or:
cd ComfyUI/custom_nodes
git clone https://github.com/KoreTeknology/ComfyUI-Nai-Production-Nodes-Pack
cd ComfyUI-Nai-Production-Nodes-Pack
pip install -r requirements.txt
Restart ComfyUI after. No model downloads - just the standard pillow/opencv requirements the pack ships. The repo bundles a brightness/contrast test workflow if you want to see the pair in action immediately. Find it under image/postprocessing; the pack deliberately files nodes into existing categories instead of creating a new root menu. The class name is Contrast Image, space included, matching what you'll see in workflow JSON.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| contrast_factor | FLOAT | 1.00–2 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |