Color: Defringe
Purple Halos on Backlit Branches? Start Here
- image
- image
Two different optical problems get called "fringing", and conflating them is why people give up and desaturate the whole edge.
Purple/green fringing (longitudinal CA) is a coloured halo hugging high-contrast edges - a branch against bright sky, a chrome highlight, a window frame. Lateral CA is a scale mismatch: red and blue are magnified slightly differently from green, so edges get red/cyan or blue/yellow outlines that grow toward the corners. One is a local colour problem, one is a global alignment problem.
Color: Defringe (JHPixelProDefringe) handles both, in that order, and leaves lightness alone so the edge stays sharp.
What it does
First the optional lateral correction. The red and blue planes are scaled about the image centre by the factor that best lines their edges up with green - found by correlating high-pass planes on a 1024 px copy, searched over roughly ±0.4%. It's applied at full size only when the edge correlation clearly improves, so a clean image isn't nudged for no reason.
Then the fringe removal. A pixel qualifies if all three hold: its hue lands in the purple band (270–335°) or the green band (75–165°), it's clearly coloured rather than near-neutral, and it sits within a few pixels of a strong luminance edge. Qualifying pixels get their Lab a* and b* pulled toward the colour of nearby non-fringe pixels, while L* is preserved. So the edge keeps its bite and loses its tint.
Only fringe pixels change. This isn't a global saturation trim.
The inputs
purple (0–1, default 1.0) - the main control, and the one you'll use.
green (0–1, default 0.0) - off by default, and the tooltip is honest about why: it can also grey out leaves seen against a bright sky. Turn it on when you've got a purple-and-green pair, and look at the foliage before and after.
lateral_ca (default on) - the plane realignment above. If your raw converter already applied lens correction, turn this off and keep only the fringe removal.
radius (0–32, default 0 = automatic, 0.15% of the long edge) - fringe width in pixels. Leave it at 0 unless a fringe survives the automatic pass; then nudge it.
Output: image.
Where this fits
Defringe before you sharpen. Smart Sharpen on a purple fringe makes it louder, and no amount of defringing afterwards quite undoes it. Defringe is also a before-you-judge step for anything backlit - the coloured halo reads as "cheap lens" and it's the sort of tell that makes an otherwise good image feel off without the viewer knowing why.
It isn't geometric distortion, though. Curved lines, barrel and pincushion bending - that's Lens Distortion in the same pack, a genuinely different problem. And it isn't a mask operation: no mask input here, it decides per pixel on hue and edge proximity.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt # the Python that runs ComfyUI
Or ComfyUI Manager → ComfyUI-JH-PixelPro → Install → restart. Node lives under Add Node → ComfyUI-JH-PixelPro → color. Requirements: kornia>=0.7, mediapipe>=0.10.33, opencv-python-headless>=4.8, scipy>=1.10; PyTorch from ComfyUI. Nothing downloads. The image is processed in strips, which is how 4K stays under 1 GB of VRAM - a detail that matters if you're batching a shoot on a small card.
Where people get burned
- Turning
greenup on a forest shot. Foliage backlit against a bright sky is the purple-green fringe scenario and also the exact situation green removal misreads. Check the leaves. - Running it after sharpening. Fringe first, sharpen second. Non-negotiable.
- Double lens correction.
lateral_caon top of an already-corrected raw gives you a fresh, subtler misalignment. Turn it off in that case. - Expecting it to fix a soft lens. Fringing isn't softness. If the whole edge is mushy, no amount of hue surgery helps.
Why bother at all, given how small fringes are? Because the list of things that make a viewer distrust an image is mostly small - grain, noise, halos, fringes - and real lenses produce fringes predictably at wide apertures and in backlight. Cleaning them, like cleaning chromatic aberration and adding a little grain, is cheap realism maintenance.
Pack context: Apache-2.0, maintained by JH (@jetthuangai), v1.10.0, 64 nodes, EN/VI docs. It has no Reddit footprint worth citing - searching the pack name in the corpus turns up one unrelated browser extension - so treat the node's own tooltips as the documentation, which in this case is genuinely specific about the leaf problem.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Photo with coloured edges (backlight, branches against the sky, chrome). | |
| purple | FLOAT | 1.000–1 | Remove purple / magenta fringes next to strong edges. |
| green | FLOAT | 0.000–1 | Remove green fringes. Off by default: it can also grey out leaves seen against a bright sky. |
| lateral_ca | BOOLEAN | true | Also line up the red and blue planes with green (red/cyan outlines toward the corners). Only applied when it clearly helps. |
| radiusopt | INT | 00–32 | Fringe width in pixels; 0 = automatic (0.15 % of the long edge). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |