Dither by channel
Separate your art into printable colors, dithered
- image
- CH1
- CH2
- CH3
- CH4
- OVERLAY
Dither by channel is the fancy sibling in the ComfyUI-Dither pack, and it exists for one reason: real-world print. Its plain sibling just dithers your image to two colors; this one splits the image into RGB or CMYK channels, dithers each channel independently with its own settings and its own ink color, then blends them back together. The result is that classic multi-color printed look - the four-color newsprint or risograph separation where you can actually see the red pass, the blue pass, the black pass doing their own thing.
Reach for it when a single flat dither isn't enough and you want that expensive, screen-printed texture, or when you're genuinely prepping art for a print shop and want to eyeball the separations. If you just want "my image but dithered," skip it and use the simple Dither node instead - this one hands you five outputs and 35-ish parameters whether you want them or not.
How it works
The mechanism is where it gets interesting. Pick color_space and the node either pulls apart the RGB channels or converts to CMYK (using the standard naive conversion: K from max channel, then C/M/Y scaled off it). Each channel then goes through the same dithering machinery as the simple node - method, threshold, contrast, brightness, gamma, grain, dot size, scale - but instead of snapping to two colors, each channel becomes an RGBA layer: a flat layer of your chX_color ink with the dithered pattern driving the alpha mask. Then all the layers get composited over bg_color using the blend_mode you choose (multiply, screen, overlay, add, darken, lighten), and that combined result is the OVERLAY.
The inputs that matter
- color_space -
RGB(three channels, good for on-screen riso-style looks) orCMYK(four channels, closer to real printing). - blend_mode - how the channel layers combine.
multiplyis the ink-on-paper default and the one you'll use most;screenandaddbrighten,overlaypunches contrast. - bg_color - the paper color the layers sit on. Default white; try a warm cream to sell the print illusion.
Then each channel gets a full set: ch1_* through ch4_*, covering method, threshold, contrast, brightness, gamma, grain, dot_size, color, and scale. The defaults are sensible - ch1 red, ch2 green, ch3 blue, ch4 black, all on Atkinson - so you can wire it up and start tweaking channel by channel. That's the fun part: push one channel's threshold way up or swap its color and the whole character of the piece changes.
The five outputs
CH1, CH2, CH3, CH4 are the flattened individual channel layers (each with the background applied, so they're standalone images), and OVERLAY is the composited final result. You almost always want to save OVERLAY. The individual channels are for inspection - and for real print workflows, where each separation genuinely is a separate plate.
Two gotchas from the way it's built. In RGB mode there is no fourth channel: CH4 comes out as a flat bg_color image, which confuses everyone the first time. And those per-channel layers are composited at the largest channel's size, with everything else upscaled to match, so channels processed at different scale values get aligned for the OVERLAY but can have slightly different native resolutions.
Installing it
Same pack, one install covers both nodes. Via ComfyUI Manager, search ComfyUI-Dither. Or manually:
cd ComfyUI/custom_nodes/
git clone https://github.com/jnxmx/ComfyUI-Dither.git
pip install -r ComfyUI-Dither/requirements.txt
Restart after installing. The dependencies are numpy, opencv-python-headless, and numba - and numba matters here even more than on the simple node, because each channel runs its own Atkinson diffusion pass. Without numba you're running four pure-Python pixel loops and it shows. No model downloads, no API keys, nothing else to set up.
Expect to spend your first session just poking the per-channel sliders - that's the node, and that's the fun of it.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| color_space | COMBO | 2 options: RGB, CMYK | |
| blend_mode | COMBO | 6 options: multiply, screen, overlay, add, darken, lighten | |
| bg_color | STRING | #FFFFFF | — |
| ch1_method | COMBO | 2 options: atkinson, halftone | |
| ch1_threshold | FLOAT | 160–255 | — |
| ch1_contrast | FLOAT | 1500–200 | — |
| ch1_brightness | FLOAT | 650–200 | — |
| ch1_gamma | FLOAT | 2.00.1–10 | — |
| ch1_grain | FLOAT | 80–100 | — |
| ch1_dot_size | INT | 61–100 | — |
| ch1_color | STRING | #FF0000 | — |
| ch1_scale | FLOAT | 2.00.1–10 | — |
| ch2_method | COMBO | 2 options: atkinson, halftone | |
| ch2_threshold | FLOAT | 160–255 | — |
| ch2_contrast | FLOAT | 1500–200 | — |
| ch2_brightness | FLOAT | 650–200 | — |
| ch2_gamma | FLOAT | 2.00.1–10 | — |
| ch2_grain | FLOAT | 80–100 | — |
| ch2_dot_size | INT | 61–100 | — |
| ch2_color | STRING | #00FF00 | — |
| ch2_scale | FLOAT | 2.00.1–10 | — |
| ch3_method | COMBO | 2 options: atkinson, halftone | |
| ch3_threshold | FLOAT | 160–255 | — |
| ch3_contrast | FLOAT | 1500–200 | — |
| ch3_brightness | FLOAT | 650–200 | — |
| ch3_gamma | FLOAT | 2.00.1–10 | — |
| ch3_grain | FLOAT | 80–100 | — |
| ch3_dot_size | INT | 61–100 | — |
| ch3_color | STRING | #0000FF | — |
| ch3_scale | FLOAT | 2.00.1–10 | — |
| ch4_method | COMBO | 2 options: atkinson, halftone | |
| ch4_threshold | FLOAT | 160–255 | — |
| ch4_contrast | FLOAT | 1500–200 | — |
| ch4_brightness | FLOAT | 650–200 | — |
| ch4_gamma | FLOAT | 2.00.1–10 | — |
| ch4_grain | FLOAT | 80–100 | — |
| ch4_dot_size | INT | 61–100 | — |
| ch4_color | STRING | #000000 | — |
| ch4_scale | FLOAT | 2.00.1–10 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| CH1 | IMAGE | — |
| CH2 | IMAGE | — |
| CH3 | IMAGE | — |
| CH4 | IMAGE | — |
| OVERLAY | IMAGE | — |