Image to Pixel Art
Image to Pixel Art — real, hard-edged pixels with retro palettes, not a cheap filter
- image
- pixel_art
Most "pixel art" generators are lying to you. They shrink the image and call it done, and you end up with mushy blended blocks that look like a JPEG at 2% quality. This node does the real thing: it downscales to a discrete low-resolution pixel grid, quantizes colors down to a limited palette, optionally dithers, then scales back up with nearest-neighbor so every pixel block is hard-edged and solid - no anti-aliasing, no blending, no cheating. If you want an honest retro look, this is the node.
How it works
The pipeline is three steps, and the order matters:
- Downscale to a pixel grid.
pixel_sizesets how many original pixels become one pixel-art pixel - 8 on a 512px image gives a 64×64 grid. Thedownscale_filtercontrols the averaging: "Box (smooth)" averages each block before quantizing (better color), "Nearest (harsh)" samples a single pixel (harder, more aliased, more authentically crunchy). - Quantize to a palette. Either a fixed historical palette or an auto-computed one. This is where the retro character comes from.
- Dither (optional). Floyd-Steinberg error diffusion, or ordered Bayer at 2×2 / 4×4 / 8×8. Dithering is what lets a 4-color GameBoy palette still render gradients.
Then upscale_to_original (on by default) scales the grid back to the original size with nearest-neighbor so the blocks are visible; disable it to get the raw low-res art as output.
Inputs and outputs
image- anything from a Load Image or a generated frame.pixel_size(default 8, 1–128) - the chunkiness dial. Bigger = chunkier.num_colors(default 32, 2–256) - max palette size, but only for the Auto and Grayscale palettes.dithering- None, Floyd-Steinberg, or Bayer 2×2/4×4/8×8.palette- the fun one: Auto, Grayscale, C64 (16), CGA (16), GameBoy (4), NES (52), Pico-8 (16). Each is a faithful fixed palette, so the output genuinely reads as "that machine".downscale_filter- Box (smooth) or Nearest (harsh).upscale_to_original- boolean.
Output is a single pixel_art IMAGE.
When to reach for it
Game assets and mockups, album-cover vibes, profile pictures, or turning a generated portrait into something that looks like it came off a Game Boy screen. The fixed palettes are the killer feature - GameBoy (4) with Bayer dithering produces that unmistakable LCD look that no "reduce resolution" filter ever gives you.
Install
Part of the vsLinx pack. ComfyUI Manager → search "ComfyUI vsLinx Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/vslinx/ComfyUI-vslinx-nodes.git comfyui-vslinx-nodes
Restart and find it under vsLinx/image as "Image to Pixel Art". No extra dependencies - the dithering and palette code runs on PIL and numpy that ComfyUI already ships.
The honest take
For a one-input fun node it's surprisingly well-made - the ordered Bayer dithering against fixed palettes is the kind of thing most "pixel art" nodes skip, and it's what makes the output actually look like hardware. The main trap is dithering choice: on the 4-color palettes, no dither gives you big flat bands (sometimes exactly what you want for a chunky sprite) while Floyd-Steinberg gives that grainy scanline texture. Try GameBoy with Bayer 4×4 and GameBoy with None side by side - they're almost different art styles.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| pixel_size | INT | 81–128 | How many original pixels make up one pixel-art pixel. 8 on a 512px image → 64×64 pixel grid. |
| num_colors | INT | 322–256 | Max palette size when using Auto or Grayscale palette. |
| dithering | COMBO | Floyd-Steinberg | 5 options: None, Floyd-Steinberg, Bayer 2x2, Bayer 4x4, Bayer 8x8 |
| palette | COMBO | Auto | 7 options: Auto, Grayscale, C64 (16), CGA (16), GameBoy (4), NES (52), +1 |
| downscale_filter | COMBO | Box (smooth) | Box averages each pixel block before quantizing (better color). Nearest samples a single pixel (harder, more aliased). |
| upscale_to_original | BOOLEAN | true | Scale the pixel grid back to the original image size using nearest-neighbor so each pixel block is clearly visible. Disable to output the raw low-resolution pixel art. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pixel_art | IMAGE | — |