arkennemasis Region Recolour (deterministic, exact)
Repaint one region to an exact hex and not a pixel outside it moves
- plate
- region_mask
- image
- report
- pixels_changed
Some variations don't need a model at all. A product where the only change is "the top panel is now #B7410E" is a retint, not a regeneration - and ArkRegionRecolour is the node that treats it that way. It recolours one masked region to an exact hex while keeping the plate's own shading, highlights and shadow. No model, no API call, no cost, and - the part that matters for a product pipeline - no possibility of frame drift, because every pixel outside the mask is bit-identical to the plate.
This is the deterministic half of the pipeline's Gen Route split. Reference-image axes (where the client supplied a photo of a material) go to the generator; hex axes can come here, instantly and exactly. It's free, it's deterministic, and it cannot drift by construction - three things no image model can promise you.
How it works
The recolour works in CIELAB rather than sRGB, because that's where "change the hue, keep the shading" is a clean operation instead of a fight. With preserve_luma on (the default), it keeps the plate's lightness structure and only re-levels the region's average to the target - so the fold in the fabric still reads as a fold, just in the new colour. Turn preserve_luma off and it replaces lightness too, which flattens the surface; the tooltip warns that's almost never what you want on a photograph.
feather softens the mask edge by a few pixels so the transition reads photographic rather than cut out. It's applied to the alpha only, never to the colour, so it can't bleed the new colour outside the region.
Inputs and outputs
plate- the locked base plate. The only required input.cell_json- wire this. Give the node a cell and it paints every one of that cell's hex axes, each into its own region, in one pass.plate_lock_json- supplies each region's mask, socell_jsonalone resolves everything.region_mask+target_hex- the single-region fallback, used only whencell_jsonisn't wired.preserve_luma,strength(1.0 = exact; lower = tinted),feather(1.5).image- the recoloured result.pixels_changed,report- so you can see the work actually happened.
Install and gotchas
Part of the arkennemasis pack:
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install -r ComfyUI/custom_nodes/comfyui-arkennemasis/requirements.txt
Restart, or install by repo URL through ComfyUI Manager.
Two traps. First: on a product whose axes all specify colours, wiring only region_mask/target_hex paints the leading axis and silently leaves every other one untouched. That's why cell_json is the preferred path - one wire, every hex axis, in one pass. Second: a cell with no hex axis raises rather than guessing - reference-image axes belong to the generator, and this node will tell you so. And if the plate has no mask for a region the cell wants, it stops the run rather than delivering images that were never changed. That refusal to fake it is the difference between a tool and a liability.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| plate | IMAGE | The locked base plate. | |
| cell_jsonopt | STRING | Preferred. Wire the cell and this node paints EVERY one of its hex axes, each into its own region, in one pass. With a product whose axes all specify colours, wiring only region_mask/target_hex would paint the leading axis and silently leave every other one untouched. | |
| plate_lock_jsonopt | STRING | Supplies each region's mask, so cell_json alone is enough to resolve everything. | |
| region_maskopt | MASK | Single-region fallback, used only when cell_json is not wired. | |
| target_hexopt | STRING | Single-region fallback, used only when cell_json is not wired. | |
| preserve_lumaopt | BOOLEAN | true | Keep the plate's lightness structure and only re-level the region's average to the target. Off replaces lightness too, which flattens the surface — almost never what you want on a photograph. |
| strengthopt | FLOAT | 1.000–1 | Blend towards the new colour. 1.0 is exact; lower only for a tinted rather than repainted look. |
| featheropt | FLOAT | 1.50–32 | Soften the mask edge by this many pixels so the transition reads photographic rather than cut out. Applied to the alpha only, never to the colour, so it cannot bleed the new colour outside the region. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| report | STRING | — |
| pixels_changed | INT | — |