Pixel Art Converter Parallel
Pixel Art Converter — an actual pixel-art algorithm, not a Resize node wearing a costume
- image
- IMAGE
- FLOAT
A lot of "pixel art" nodes are just nearest-neighbor downscales - shrink the image, call it pixel art, move on. The results look like a postage stamp, not pixel art. This one is different: it estimates the actual pixel size in the source, block-averages, and quantizes colors with dithering. It's an actual conversion pipeline, and the "Parallel" in the name means it spreads the work across threads instead of grinding through the image serially.
Where you'd reach for it: turning AI generations into sprite-style art for game assets, making chunky pixelated versions of renders for stylistic consistency, or any "I want this to look like a 16-bit sprite" job where the cheap resize trick isn't good enough.
How it works
The pipeline has three real stages. First it estimates the optimal pixel block size - how many source pixels should collapse into one pixel-art pixel - by analyzing the image's frequency content and its edge spacing, then blending the two guesses with a weighted average. This is what stops everything from looking uniformly blocky: a detailed image gets a smaller pixel size, a flat image gets a bigger one.
Then it does the actual pixelation by averaging blocks at that size, and finally it runs color quantization using k-means clustering with a palette size that depends on your palette_type, followed by Floyd–Steinberg dithering to stop banding in gradients. That dithering pass is the difference between a posterized mess and something that reads as intentional.
The parallel bit: size estimation and per-block processing run across a ThreadPoolExecutor, so it uses idle CPU cores rather than sitting on one.
The inputs
image(IMAGE) - what you're converting.palette_type- the enum with the Portuguese names:muito_limitada(very limited, 16 colors),limitada(limited),muitas(many),sem(none - no forced palette, just pixelation). Yes, the labels are in Portuguese. The author's in there somewhere and didn't translate his enum; roll with it.min_size/max_size- the allowed range for the estimated pixel block size, defaults 2 to 32. Bumpmin_sizeup if you want chunkier results guaranteed.
Outputs: IMAGE (the pixel art) and a FLOAT - the estimated pixel size it settled on. That FLOAT is useful for chaining: feed it into the non-parallel converter or a workflow that needs to know the scale factor.
Installing it
Part of the AnotherUtils pack:
cd ComfyUI/custom_nodes
git clone https://github.com/marcoc2/ComfyUI-AnotherUtils.git
Restart ComfyUI, or use ComfyUI Manager (search "AnotherUtils"). This one does lean on scipy, scikit-learn, and opencv-python - the pack has no requirements.txt, so make sure those are present in your ComfyUI environment; most installs already have opencv, and scikit-learn is common, but if the node throws an import error that's the first thing to check.
Gotchas
It's CPU-bound and the estimation stage can be slow on big images - that's what the parallel processing is trying to offset, but don't expect real-time. If the estimation fails internally it quietly falls back to min_size, so you can get chunky results on an image that should've been fine-grained - if output looks unexpectedly blocky, that's the failure mode, not a feature.
And remember the alpha reality: it processes the first frame of a batch and expects RGB. RGBA sources get their alpha dropped in the conversion. If you need the transparency preserved for sprites, convert alpha to a mask separately and re-apply. For turning renders into chunky stylized art, though, this is one of the better pixel-art nodes in the ecosystem.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| palette_type | COMBO | 4 options: muito_limitada, limitada, muitas, sem | |
| min_size | INT | 21–32 | — |
| max_size | INT | 322–64 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| FLOAT | FLOAT | — |