ComfyUI Node Runs on cloud

Image Quantize

The palette step your pixel art was missing

By WASasquatch·Created 4 years ago·Updated a day ago· 1,864
Image Quantize
  • image
  • IMAGE
◄colors256►
◄dither▾►

Diffusion models do not make pixel art. They make something that looks like pixel art from a metre away: soft, off-grid, three hundred colours deep. The composition is the model's job; the pixels are a deterministic post-process, and palette reduction with dithering is the middle step of that process. This node is the middle step.

It's also the node you want for anything else that needs to be pushed into a small number of flat colours - poster art, stencil and screenprint mockups, a 16-colour palette for consistency across a set of frames, or getting rid of gradient banding by replacing the smooth ramp with honest steps.

How it reduces

Each frame is quantised on its own with median cut - Pillow's palette builder, the same one behind GIF and indexed PNG - to the number of colours you ask for. Every frame in a batch gets its own palette, derived from its own pixels, and the frames are run in parallel on a thread pool (up to eight at a time, capped by your CPU count), so a 120-frame clip doesn't take 120 times as long as one image.

colors runs from 1 to 256, default 256. The useful readings: 256 is nearly invisible on photographic content and mainly removes gradient banding; 32–64 is a stylised but still natural look; 16 is unmistakably posterised, and it's the count the classic hardware palettes use; 2 gives you a two-tone image, which is a great way to check what dithering is actually doing before you commit to a look.

dither decides what happens to the colours that didn't make the cut:

  • none throws them at the nearest palette entry. Flat bands, hard edges between tonal regions.
  • floyd-steinberg diffuses the rounding error into neighbouring pixels as scattered noise. Gradients survive at surprisingly low colour counts; it's the classic photo-quantisation choice.
  • bayer-2 through bayer-16 lay a fixed ordered pattern instead, from fine to coarse. Regular stipple rather than random - this is the retro/hardware look, and it's what makes a 16-colour image read as intentionally 16 colours rather than as a bad JPEG.

Output is a single IMAGE batch, quantised, ready to wire into a save node, a morphology pass to tidy the edges, or an integer nearest-neighbour upscale when you're building actual pixel art.

Where it fits in a real pipeline

The pixel-art recipe, in order, is: get the model to produce the composition; find the true block size and downscale with block-wise voting (not averaging, or you get mush); reduce the palette with dithering; then scale back up with nearest-neighbour. This node is step three. It is not going to give you a pixel grid on its own - a downscaled-but-unquantised image still has hundreds of colours, and a quantised image at full resolution still has anti-aliased non-pixel edges. Both halves matter, and the community position on this is unanimous and has been since 2023.

For animation specifically, the per-frame palette is the thing to know about. A 24-frame loop where each frame picks its own palette will shimmer as colours drift between frames - usually fine for a noisy shot, often ugly for a flat cel-shaded one. There's no shared-palette mode here, so it's empirical: try 24–32 colours with bayer dither and see whether the drift reads as grain or as flicker. Coarser ordered dither hides palette differences better than floyd-steinberg does.

Alpha gets special treatment: on a four-channel image, alpha is copied through untouched while RGB is quantised. So you keep clean transparency and a smooth anti-aliased cut-out edge, and the colour inside it is posterised. That's the behaviour you want and it's worth knowing before you wonder why the edges look softer than the fill.

Treat it as destructive

Quantisation is not adjustable after the fact. It's a lossy step, it's cheap, and the honest workflow is to keep a full-colour save alongside the reduced one - Fast Save Animated WEBP or another save node on the same batch costs you nothing and gives you something to re-quantise from when you change your mind about the palette size. Don't put this early in a chain you're still iterating on; every node downstream inherits the bands.

Installing it

ComfyUI Manager → search WAS Node Suite v3 → Install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git

ComfyUI 0.14.0+ and Python 3.10+. No packages to install - the pack's default requirements list is empty, nothing gets pip-installed and nothing gets downloaded, and this node's helpers are Pillow, numpy and torch, all of which ComfyUI already brings. The first start after install is a second or two slower while the pack writes config.yaml, its state database and the wildcard and LUT folders under <ComfyUI user dir>/was-node-suite/; updates recompile the bytecode once.

If a guide tells you to run install.bat, install a requirements file, or pin opencv to make WAS Suite work, it's a v2 guide: v2 carried about twenty dependencies and could genuinely break a working install. v3 carries none, which is why the old troubleshooting threads no longer match what you'll hit.

The two surprises

colors at 256 on an already-8-bit image looks like it did nothing. In flat areas it did nothing, and in smooth gradients it removed a bit of banding - the palette size isn't the lever, the dither is. Second: high colour counts with none dither produce hard banding that's more visible than the original, because you've snapped a smooth ramp to 60 steps. If you're quantising to see a difference, go to 16 or 32 with floyd-steinberg and you'll see exactly what the node does.

CategoryWAS Suite/Image/Filter

Inputs (3)

NameTypeDefaultDescription
imageIMAGEThe frames to reduce. Each gets its own palette.
colorsINT2561–256Palette size. `256` is nearly invisible, `16` is posterised, `2` is two tones.
ditherCOMBO`none` gives flat bands, `floyd-steinberg` scatters noise to hide them, `bayer-2` to `bayer-16` lay a regular pattern, coarser as the number rises.

Outputs (1)

NameTypeDescription
IMAGEIMAGEThe reduced frames, alpha kept as it was.