🕹️PixelArt Detector (Image->)
1 pixels
- images
- IMAGE
Prompt pixelart, blocky, 8-bit graphics on SDXL and you know what you get: something that reads as pixel art at thumbnail size and turns into soft mush at 1:1. Diffusion models paint at their native resolution. They don't lay down crisp squares - that part is on you. This node is the cleanup step that's missing from that pipeline. It looks at your image, works out how big the "pixels" a human artist would have used actually are, and downsamples to exactly that size with hard edges intact. It's the most-used node in the ComfyUI PixelArt Detector pack for a reason.
How it actually works
The node is a wrapper around Astropulse's pixeldetector algorithm. The core trick is cheap and clever: scan every row and column, compute the color difference between adjacent pixels, then find the peaks - the column/row boundaries where the image actually changes. The median spacing between those peaks is the pixel size. Each resulting tile is averaged down to its dominant color, and you get a clean blocky image at true pixel resolution instead of a resized blur.
Version 1.7 added a guard on top of that: downscale_to_1x_keep_ar forces a single uniform integer scale, so uncommon aspect ratios don't get the horizontal and vertical axes stretched by different amounts. That was a real bug before - wide images could come out distorted. It's all plain NumPy/Pillow math on the CPU, so this runs in milliseconds, not seconds.
The inputs that matter
Only three, and you'll touch two of them:
- images - any IMAGE tensor. Batches are handled per-image.
- reduce_palette - off by default. Flip it on and the node also cuts the image down to a small color count, which is most of what makes something look like pixel art.
- reduce_palette_max_colors - default 128. This is an upper bound, not a hard target: the node runs an elbow-method analysis over candidate k values and picks the color count where adding more colors stops helping. Set it lower (32–64) for a chunky retro look.
The output is a single IMAGE tensor.
Where it goes in a workflow
Classic path: KSampler → VAE Decode → PixelArt Detector (Image->) → PixelArt Palette Converter → Save. It forwards the cleaned image instead of saving it, which is the whole point of this variant - the pack's other nodes save, resize, or recolor, and this one just hands you crisp pixels to keep processing.
If you want a display-sized image afterwards, upscale with nearest-neighbor interpolation. Don't reach for an ESRGAN-style upscaler here; those are built for adding photographic detail and will smear your blocky edges. For pixel art the correct "upscale" is just repeating the pixels.
The author's example workflows pair the pipeline with the Pixel Art XL LoRA by NeriJS for generation, then this node fixes the output. That combo is worth copying: generate, downscale to real pixels, then upscale with nearest.
Installing the pack
This node ships in dimtoneff/ComfyUI-PixelArt-Detector. Easiest route is ComfyUI Manager - search "ComfyUI PixelArt Detector" and install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/dimtoneff/ComfyUI-PixelArt-Detector
Restart ComfyUI. On first load the pack auto-installs its Python deps (opencv-python, scipy, pyclustering, Pillow, numpy). The pyclustering bit is the one that bites: it has no wheels for newer Python versions, so the pack downloads a prebuilt wheel from the author's GitHub releases on startup - fine on x86_64, but it can fail on Apple Silicon or odd Python builds. If it does, install pyclustering yourself with pip and restart.
Gotchas
- Outdated embedded nodes: if a workflow you downloaded keeps the old node version, delete the node and add it again from the Image/PixelArt menu. Old instances don't update cleanly.
- This node never upscales. It only downsamples to 1:1 pixel size. If you want a specific output dimension, that's the Converter's or the Save node's job.
- It's not magic for badly-generated images - feed it something that's already readable as pixel art and it sharpens it; feed it a blurry mess and you get a blocky blur.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| reduce_palette | BOOLEAN | false | — |
| reduce_palette_max_colors | INT | 1281–256 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |