Nodes/ComfyUI-image-processor-zn123/Adjust Contrast @zn123
ComfyUI Node

Adjust Contrast @zn123

Contrast, minus the mystery (and minus a working README range)

By zn123·Created 9 months ago·Updated 5 months ago· 0
Adjust Contrast @zn123
  • image
  • adjusted_image
contrast1.0

Flat, washed-out generations are a ComfyUI staple - especially at low CFG or with sloppy negative prompts. Adjust Contrast @zn123 is the quick fix: drop it in the graph, push one number, and your image gets some life back before it ever reaches an upscaler or the final save. It's the partner to the pack's Adjust Brightness node, and it does exactly one thing.

What it actually does

Same pattern as its sibling: it's a thin wrapper around Pillow's ImageEnhance.Contrast. Each frame in your batch tensor gets converted to a PIL image, run through the enhancer, and converted back to ComfyUI's IMAGE format. Pure pixel-space math, no model, no weights, no VRAM beyond the image itself. A batch of frames is processed frame-by-frame, so it's equally happy on a single reference image or a stack of video frames.

You set one input: contrast, a FLOAT from 0 to 3 (step 0.1, default 1). And same warning as the brightness node: the README says the range is -1.0 to 1.0 with "0 = no change," and that is wrong in both directions. Contrast here is a multiplicative factor in PIL terms:

  • 1.0 - no change (the default)
  • 1.2 to 1.5 - a gentle punch, good for fixing flat output
  • 2.0+ - harsh, crunchy, only for a deliberate look
  • 0.5 - softer, lower-contrast
  • 0.0 - solid gray

Set it to 0 thinking you're at "no change" per the README and you'll get a completely desaturated gray frame. 1.0 is the identity value, not 0. That stale README range is the one real trap in this node; the shipped code is fine.

Where it fits

The textbook move is a brightness-then-contrast pass between LoadImage and whatever consumes the image: contrast 1.3 after a brightness 1.1 on a reference photo that's both dim and flat makes a real difference to how well ControlNet or IPAdapter conditioning reads it. It's also handy before an upscaler, because pushing contrast while the image is small is a lot cheaper than doing it at 4x resolution - garbage in, garbage out applies to detail recovery too.

It outputs a single adjusted_image (type IMAGE), which plugs straight into any IMAGE input downstream. If you want to see the effect, wire it into a SaveImage or PreviewImage and toggle the value.

Installing it

It ships in the ComfyUI-image-processor-zn123 pack, installed like any custom node:

  • ComfyUI Manager - search "ComfyUI-image-processor-zn123", install, restart.
  • Manual - from ComfyUI/custom_nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/zn123/ComfyUI-image-processor-zn123

Restart ComfyUI and you'll find it under image/processor. No model files, no downloads: requirements are just torch, numpy and Pillow, which ComfyUI already has. This is a zero-friction install.

Gotchas

  • contrast is a factor. 1.0 is identity, 0.0 is gray, and the README's "-1 to 1, 0 = no change" is fiction. Trust the node's own min/max, not the docs.
  • Contrast correction amplifies noise on underexposed areas. If your source is dark and grainy, brighten first, contrast second, and don't crank past ~1.5 or you'll be feeding an upscaler a noisy mess.
  • Like every node in this pack, it's pixel-space, not latent-space. It changes how pixels look; it doesn't resynthesize. That's the right tool for preprocessing and the wrong one if you're hoping it'll rescue a genuinely broken render.

Flat image, one slider, done. Just keep it away from 0.

Categoryimage/processor

Inputs (2)

NameTypeDefaultDescription
imageIMAGE
contrastFLOAT1.00–3

Outputs (1)

NameTypeDescription
adjusted_imageIMAGE