ComfyUI Node

Tone Refiner

Fix the grade, rescue the highlights, upscale, and fake a DOF — in one pass

By Code2Collapse·Created 6 months ago·Updated a day ago· 52
Tone Refiner
  • image
  • latent
  • vae
  • upscale_model
  • depth_map
  • refined_image
  • refined_latent
neural_correctortrue
corrector_tone0.60
corrector_color0.40
highlight_protection0.50
shadow_lift0.00
enable_upscalefalse
upscale_factor1.50
ai_enable_doffalse
ai_dof_strength1.00
ai_dof_focus_depth0.70
auto_upscaletrue

The image came back too dark, the highlights are clipped, the white balance is off, and maybe it could stand to be bigger. Tone Refiner (MEC) is the catch-all finishing node that addresses all of that in one shot: deterministic tone + gray-world color correction, optional upscale, and an optional depth-of-field blur. It's the "make it look finished" node at the end of the pack's paint suite.

The one thing to know up front: despite the neural_corrector name, there's no neural network here. It's deterministic image math - black/white-point stretching and gray-world color balancing. "Neural" is branding; the node is fast, predictable, and needs no model.

How it works

neural_corrector (default on) does the tone work. corrector_tone (default 0.6) blends toward the tone-corrected image - black/white-point stretch - and corrector_color (default 0.4) blends toward gray-world color balance (which kills color casts). Two nice touches: highlight_protection rolls off the top 5% to stop clipping, and shadow_lift lifts the bottom 5% on the dark side. The defaults are conservative enough that the result looks "fixed" rather than "graded."

Then the extras:

  • enable_upscale + upscale_factor (default 1.5) - uses upscale_model if you connect one (RealESRGAN, 4x-NMKD, whatever), bicubic otherwise.
  • ai_enable_dof + ai_dof_strength + ai_dof_focus_depth - a depth-of-field blur. Connect a real depth_map and it's depth-driven; leave it disconnected and you get a fake center-focus radial gradient. It's a stylization, not optics - great for a product shot thumbnail, wrong for anything where real defocus matters.
  • latent/vae/auto_upscale - the latent side. With a vae supplied and auto_upscale true (default), it VAE-encodes the refined image into refined_latent so you can feed the corrected result straight back into a sampler. Skip the VAE and refined_latent is a zero placeholder.

Outputs: refined_image and refined_latent.

Where it fits

In the suite it's the grade-after-fix stage: Context Inpainter blends the inpaint back, Tone Refiner fixes the tonal drift that inpainting introduced, and the latent output hands the sampler a clean starting point. Standalone, it's a surprisingly useful one-stop for "my image is dark and casty and small" - most of that is the tone correction alone.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
pip install opencv-python>=4.7.0 scipy>=1.10.0

or ComfyUI Manager → search "CustomNodePacks", restart, confirm [MEC] Loaded .... No model downloads - the correction is math. If refined_latent comes back as zeros, you either skipped the VAE or auto_upscale is off, and that's the documented behavior, not a bug.

CategoryC2C/Paint

Inputs (16)

NameTypeDefaultDescription
imageIMAGEImage to refine.
neural_correctorBOOLEANtrueEnable deterministic tone + gray-world correction (not a learned model).
corrector_toneFLOAT0.600–1Blend amount toward the tone-corrected image (0 = original, 1 = full correction).
corrector_colorFLOAT0.400–1Blend amount toward the gray-world color-corrected image.
highlight_protectionFLOAT0.500–1Roll-off applied above 95th-percentile to prevent highlight clipping (0 = none, 1 = strong).
shadow_liftFLOAT0.000–1Lift shadows below the 5th-percentile (0 = none, 1 = strong; mirrors highlight_protection on the dark side).
enable_upscaleBOOLEANfalseUpscale by upscale_factor; uses upscale_model if provided, bicubic otherwise.
upscale_factorFLOAT1.501–4Upscale multiplier applied when enable_upscale is True.
ai_enable_dofBOOLEANfalseApply depth-based DOF (uses depth_map if connected, else fake center-focus).
ai_dof_strengthFLOAT1.000–4Strength of the DOF blur (also scales the maximum blur radius).
ai_dof_focus_depthFLOAT0.700–1Focus plane: when depth_map is connected this is the in-focus depth value (0=near,1=far); without depth_map it controls center-focus tightness.
latentoptLATENTOptional pre-existing latent; passed through when supplied (skips VAE encode).
vaeoptVAEVAE used to encode the refined image into refined_latent (when auto_upscale is True).
upscale_modeloptUPSCALE_MODELOptional UPSCALE_MODEL (RealESRGAN / 4x-NMKD / etc.). When connected and enable_upscale is True, used instead of bicubic and resized to upscale_factor.
depth_mapoptMASKOptional depth map (0=near,1=far). Drives DOF when connected; replaces the fake center-focus radial gradient.
auto_upscaleoptBOOLEANtrueWhen True (default, back-compat), encode the refined image through the supplied VAE to produce `refined_latent`. Set False to skip the VAE-encode and return a zero placeholder.

Outputs (2)

NameTypeDescription
refined_imageIMAGETone- and color-corrected image (optionally upscaled and DOF-blurred).
refined_latentLATENTVAE-encoded latent of the refined image (zero placeholder when auto_upscale is False).