Nodes/ComfyUI 1hewNodes/Match Brightness Contrast
ComfyUI Node

Match Brightness Contrast

Make one image's light match another's — and keep it stable across frames

By 1hew·Created about a year ago·Updated 7 days ago· 33
Match Brightness Contrast
  • source_image
  • reference_image
  • image
edge_amount0.20
consistencylock_first
methodhistogram

Two images, one of them looks wrong next to the other - too dark, too flat, different exposure. Match Brightness Contrast drags the source image's brightness and contrast toward a reference image's, per color channel, so a generated frame can sit in a scene without looking pasted-on. It's the color-timing tool you reach for when a composite keeps failing on light, not on geometry.

How it works

Two methods, both operating per RGB channel. histogram (default) builds per-channel cumulative histograms of source and reference, then maps each source brightness level through the reference's distribution - the standard histogram-matching approach that reshapes the whole tonal curve, not just the average. standard is the cheaper statistical route: it measures each channel's mean and standard deviation on both images and applies (x - mean_src) * (std_ref / std_src) + mean_ref - a mean/std color transfer. Histogram is more faithful; standard is lighter.

The clever bit is edge_amount. A margin of the image (default 20% of the short side) can be used for the statistics instead of the whole frame. Why? Because if your two images show different content in the middle but the same lighting at the edges, measuring only the borders keeps the match about exposure rather than about whatever's in the center. edge_amount under 1.0 is a fraction of the short side; 1.0+ is raw pixels; 0 means use everything.

consistency exists for batches and video. frame_match recalculates per frame. The others - lock_first, lock_mid, lock_end - compute the mapping once from a chosen frame pair and apply that same mapping to every frame. That's the anti-flicker setting: recalculating per frame makes each frame individually match, but the amount of correction drifts and you get pulsing. Locking kills the drift.

The inputs that matter

  • source_image / reference_image (IMAGE) - what gets corrected / what it's corrected to.
  • edge_amount (FLOAT, default 0.2) - border-only statistics fraction. The one you'll tune first.
  • method - histogram or standard.
  • consistency - lock_first (default), lock_mid, lock_end, or frame_match.

Output: image (IMAGE), the corrected source.

Installing it

ComfyUI Manager → search ComfyUI-1hewNodes → install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/1hew/ComfyUI-1hewNodes

Restart ComfyUI. Pure tensor math, no model downloads. Pack pulls heavy requirements regardless (rembg, ultralytics, etc.), and it needs a current ComfyUI for its comfy_api.latest API.

Common issues

Batch mismatch is handled gracefully - if your source has 24 frames and the reference has 1, frames just cycle through the reference - but it means you should make sure the intent matches too. Watch the consistency trap: the default lock_first computes from frame 0, so if frame 0 is an outlier (a flash frame, a near-black frame), every frame gets corrected against that bad sample. And edge matching assumes your subjects are center-weighted; a subject that runs to the canvas edge will pollute the border statistics, so widen edge_amount or use the full frame.

Category1hewNodes/color

Inputs (5)

NameTypeDefaultDescription
source_imageIMAGE
reference_imageIMAGE
edge_amountFLOAT0.200–8192
consistencyCOMBOlock_first4 options: lock_first, lock_mid, lock_end, frame_match
methodCOMBOhistogram2 options: standard, histogram

Outputs (1)

NameTypeDescription
imageIMAGE