Nodes/pfaeff-comfyui/AstropulsePixelDetector
ComfyUI Node

AstropulsePixelDetector

The node that un-smooths your SDXL pixel art

By Pfaeff·Created 3 years ago·Updated 2 years ago· 22
AstropulsePixelDetector
  • image
  • IMAGE
max_colors128

This is the node that makes the whole "SDXL pixel art" idea in this pack work, so it's worth knowing what it actually is before you wire it up: it's not a diffusion node and it loads no model. Behind the scenes it shells out to a separate Python script - Astropulse's pixeldetector, the same codebase that powers the Retro Diffusion pixel-art generator for Aseprite - which reconstructs the original pixel grid of an image that's been upscaled, blurred, or JPEG-crushed.

The problem it solves is real and specific. SDXL cannot draw crisp pixel art. Give it a pixel-art prompt and you get something soft and anti-aliased that reads as "posterized screenshot" more than "sprite sheet." This node detects where the original pixels were and rebuilds the chunky blocks and limited palette you actually wanted. It slots into the pack's example SDXL pixel-art workflows, turning a mushy render into something that looks like it came out of a game art pipeline.

How it works

The node writes your image to a temporary PNG, then runs pixeldetector.py as a subprocess with --palette always on (the code literally has a # TODO make this a parameter there) and --max set to your max_colors. Inside the script, the clever part is grid detection: it sums horizontal and vertical color differences across every row and column, finds the peaks - those are the pixel boundaries - and takes the median spacing as the original pixel size. Each tile is then downsampled to its single most dominant color via a small k-means. With --palette on, it also runs an "elbow" search over candidate palette sizes (capped at max_colors) and quantizes the result to however many colors the curve says is right. You get a clean, limited-palette image back at the original resolution.

The whole frame is processed as one piece. There's no per-sprite mode, and if you feed it a batch of more than one image it refuses with a "Batches are not supported" error, because the detected grid size can differ per image.

The inputs that matter

Only two, and you mostly touch one:

  • image (IMAGE) - what you're repairing. The better the source, the better the detection; heavy blur or heavy compression confuses the peak-finding.
  • max_colors (INT, default 128) - the ceiling for the palette-size search. More colors means a slower run; 128 is a sane default for most pixel art.

Output is a single IMAGE - the restored, palette-limited image. Wire it into a Save Image node (or a compositor) and you're done.

How to install it

This pack is a work in progress - the README literally says "not tested, yet" - and the author, Pfaeff, has been around the community since the early diffusers days (credited in a 2022 Dreambooth conversion colab on r/StableDiffusion). It installs like any custom node:

cd ComfyUI/custom_nodes
git clone https://github.com/Pfaeff/pfaeff-comfyui

then restart ComfyUI. The install script pip-installs the pack's requirements.txt (just opencv-python-headless and diffusers) - but the pixel detector lives in a git submodule, and that's where installs go wrong.

Common issues & troubleshooting

"No such file or directory: ...pixeldetector/pixeldetector.py" - the submodule wasn't checked out. The install script's submodule line is malformed (it runs git submodule init --init --recursive, which errors), so the pixeldetector folder ships empty. Fix it manually:

cd ComfyUI/custom_nodes/pfaeff-comfyui
git submodule update --init --recursive

The submodule needs Pillow, numpy and scipy on top of the pack's own deps - if the script errors on import scipy, pip-install it into ComfyUI's Python.

"Batches are not supported" - expected, not a bug. Run it one image at a time, or use a Batch Unsplit-style node first.

It's slow - raise max_colors high enough and the palette search loops over every value up to it. Drop it to 64 or 32 for a quick preview.

The subprocess uses plain python - on Windows with an embedded Python or an odd venv, the node may invoke a different interpreter than ComfyUI uses, and you'll get confusing failures. Installing the submodule's deps into whatever python resolves to fixes it.

CategoryPfaeff/image

Inputs (2)

NameTypeDefaultDescription
imageIMAGE
max_colorsINT128

Outputs (1)

NameTypeDescription
IMAGEIMAGE