ComfyUI Node

Pixel Grid Collapse

Stop Guessing Why Your Pixel Art Has Double-Wide Pixels

By envy-ai·Created 8 days ago·Updated a day ago· 13
Pixel Grid Collapse
  • image
  • IMAGE
logical_width64
logical_height64

Here's why your "pixel art" generation looks wrong up close: the model painted something that reads as 16px blocks, except they're 15 pixels tall here and 17 wide there, because a continuous latent has never once agreed to land on a lattice. Pixel Grid Collapse is the blunt instrument that fixes it. You tell it how many logical pixels wide and tall the result should be, it merges each block into a single color, and it hands you back an image at the original resolution built from perfectly uniform cells.

How it works

The node slices the image into an even logical_width × logical_height grid of rectangular cells and reduces each cell to one color by mode, not average. Every pixel is rounded to 8-bit RGB, and the most frequent exact color in the cell wins. Averaging would invent colors that never existed and give you back the blurry mush you were escaping; the mode preserves a color the model actually painted.

Ties - two colors equally common in a cell - go to whichever is perceptually closest to the cell's center pixel in OKLab, which is why the middle of a shape wins over a fringe pixel. If even that is tied, the first matching pixel in raster order wins, so the output is deterministic run to run. Then it expands back with integer nearest-neighbour replication on both axes - not a resample. Same dimensions out as in.

Inputs and outputs

  • image - a single image or a batch.
  • logical_width - default 64, range 1–16384. Logical pixels across the output.
  • logical_height - default 64. Logical pixels down.

One IMAGE output, at the input resolution. This is the bit beginners miss: a 1024×1024 input with a 64×64 logical grid gives you back a 1024×1024 file where each "pixel" is a 16×16 block. Want a true 64×64 sprite on disk? Add an integer nearest-neighbour downscale afterwards - every block is flat by then, so it's lossless.

Both logical dimensions have to divide the image dimensions evenly, and neither can exceed the image. 1024×1024 at 64×64 is fine (16px blocks); 1216×832 at 64×64 is fine too (19 and 13); 1000×1000 is not, and the error tells you so.

Picking the number

There's no detection here - this is the "I already know my pixel size" node. If you don't know it, guess and iterate: start at 64, look at whether edges come out crisp or double-wide, then halve or double. The pack's MiniMax H3 Autorefiner detects the mesh for you; this one just obeys.

It also assumes the source grid starts at pixel zero. If the generated blocks straddle your cell boundaries by half a block you'll get seams and smear down every edge, and the offset controls that fix that only exist on this pack's MiniMax H3 nodes.

Pair it with a quantizer

Collapse alone doesn't cut color count. You get hard-edged blocks in 900 colors, which is the usual reason AI pixel art still reads as AI. Run the output into Perceptual Palette Reduce from the same pack - collapse first, quantize second. The pack also ships a combined Krea 2 Pixel Art Refiner node that does both in one pass, and most people should probably just reach for that.

Install

No models, no checkpoints, no API key. ComfyUI Manager → search Krea 2 and MiniMax H3 Pixel Art Refiners (the registry name) or the repo name. Manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/envy-ai/ComfyUI-Krea2-Pixel-Art-Refiner.git krea2_pixel_art_refiner

Restart ComfyUI and look under image/transform. The pack declares one dependency, opencv-python-headless>=4.8; there's no requirements.txt, so a manual clone installs nothing for you.

Common issues

"Image size 1000x1000 must be divisible by logical grid 64x64." Not a bug - pick divisors of your resolution, or resize first. On power-of-two canvases, 64, 32 and 16 are always safe.

"Logical grid 128x128 cannot exceed image size 64x64." You asked for more logical pixels than the image has pixels. Raise the input resolution.

Fine detail disappears. Mode voting eats it: a one-pixel highlight inside a 16×16 cell is outvoted by the background. If eyes and highlights are vanishing at 64×64, your source blocks were smaller than 16px - go up to 96 or 128 logical. You're choosing which pixel size to believe.

The node doesn't appear at all. The pack uses the newer comfy_api node API (comfy_entrypoint + ComfyExtension), so it needs a reasonably current ComfyUI, and nodes.py imports cv2 at module level - a missing opencv kills the whole pack's import, this node included. pip install opencv-python-headless in ComfyUI's environment.

No field reports to lean on. Reddit searches for this node turn up nothing, and the pack is from a one-person CivitAI model account, so the README and source are the documentation. Fine, because the operation underneath is thirty years old and deterministic.

Categoryimage/transform

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
logical_widthINT641–16384Number of logical pixels across the result.
logical_heightINT641–16384Number of logical pixels down the result.

Outputs (1)

NameTypeDescription
IMAGEIMAGE