ComfyUI Node

LC Tone Match

Put the original light back on your refined frame

By lonecatone23·Created about a month ago·Updated about 19 hours ago· 10
LC Tone Match
  • image
  • reference
  • mask
  • image
tone_match0.85
refinement_strength0.55
detail_radius32
skin_protect0.50

Here's the workflow: you generate a frame, run it through a refinement/edit pass - a Krea2 or Qwen re-render, a face fix, an H3 video frame that drifted - and the result has better detail but the lighting went sideways. The shadows are in the wrong place, the white balance wandered, the whole thing no longer sits in the same scene as the rest of your clip. LC Tone Match is the fix: it takes your refined image and your original reference, and stitches them together by frequency - the reference keeps the broad lighting and color, the refined image keeps the micro-detail. Same job as ComfyUI's native H3 Detail Tone Lock, but for any two images, not just H3 outputs.

It's a post-processing node, not a model, which is exactly the argument this whole layer makes: a deterministic frequency blend costs milliseconds and doesn't re-roll your face. When your edit already looks great except for the light, you don't re-generate - you lock the tone.

How it works

Under the hood it's a blur-and-mix, the same DNA as unsharp masking but aimed at color instead of sharpness. Both images get Gaussian-blurred at detail_radius; the blur carries the broad tone (lighting, ambient color), and subtracting it leaves the fine detail. Then:

  • tone_match (default 0.85) pushes the refined image's broad tone toward the reference's - 0 means off, 1 is full lock.
  • refinement_strength (default 0.55) decides how much of that tone-locked result actually gets mixed back over the reference. Lower it to avoid identity drift when the edit changed more than light.
  • detail_radius (default 32) sets the blur that splits "broad" from "fine". The author's guidance: ~32 for a 1–2 MP image; go bigger for higher resolution.
  • skin_protect (default 0.5) holds the reference's skin hue after the lock, so a face doesn't take on the new color cast - the same idea as LC Color Match's skin protect.

The optional mask is where this earns its keep: white = apply the lock, black = keep the refined image untouched. The classic use is a head-swap or a region you edited on purpose - paint the new head black and it keeps its own color while the rest of the frame locks back to the scene.

Output is a single image, and because the node doubles as a preview node, you get an on-node wipe against the reference so you can see the lock before it hits your save node.

The three knobs that matter

  • tone_match - how hard to pull the light back. Most edits want it high (0.8–1.0).
  • mask - white locks, black keeps. This is the difference between "match the whole frame" and "match everything except the thing I fixed."
  • detail_radius - up it with resolution. Too small and the "tone" starts dragging fine detail around; too big and the lock misses the shadows you wanted fixed.

Where people get burned

  • Same crop, or nothing. The node aligns by position, not by content. If your reference and your refined image aren't the same crop, the blur regions don't line up and you get smeared tone. Reframe first.
  • Head-swaps need the mask. Don't tone-match a swapped face and expect it to stay recognizably that face - mask off the new head (black) so the lock skips it.
  • It's not a color-match substitute. LC Color Match does full-frame statistical color transfer (the Reinhard-style mean/std job from the post-processing world). Tone Match is a frequency lock - it restores the reference's broad lighting over your detail, not its exact palette. Reach for the right tool: palette off → Color Match; lighting off → this.

Install

It's part of LC123, which has no extra dependencies - install once, get all ~90 nodes:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes

or via ComfyUI Manager (search "ComfyUI_LC123_nodes"), then restart. No model downloads needed for this node - it's pure pixel math. The one layout trap to dodge: __init__.py must sit directly in the pack folder, not a nested ComfyUI_LC123_nodes/ComfyUI_LC123_nodes/; if you unzipped into an existing clone, move the inner files up a level.

CategoryLC123/image

Inputs (7)

NameTypeDefaultDescription
imageIMAGEThe refined / generated image (Krea2, Klein, Qwen, etc.). High-frequency is taken from here.
referenceIMAGEOriginal / H3 still. Authority for size, broad lighting, and color.
tone_matchFLOAT0.850–1How hard to restore source low-frequency lighting/color. 0 = off, 1 = full lock.
refinement_strengthFLOAT0.550–1How much of the tone-locked refine is mixed over the source. Lower = less identity drift.
detail_radiusINT322–64Blur radius splitting broad tone from fine detail. ~32 for 1–2 MP.
skin_protectFLOAT0.500–1Hold reference skin hue after the lock (0 = off). Same idea as Color Match.
maskoptMASKWhite = apply lock. Black = keep image as-is (use for a new head / edited region).

Outputs (1)

NameTypeDescription
imageIMAGE