Nodes/comfyui-properpixelart/Proper Pixel Art Video / GIF
ComfyUI Node

Proper Pixel Art Video / GIF

Pixelate an animation without the flicker

By unclepomedev·Created 23 days ago·Updated 2 days ago· 1
Proper Pixel Art Video / GIF
  • config
  • output_path
◄input_path▾►
◄num_colors0►
◄initial_upscale_factor2►
◄pixel_width0►
◄scale_result1►
◄transparent_backgroundfalse►
◄num_sample_frames8►
◄output_formatgif►
◄intermediate_dir►

Here's the thing about pixelating a video: if you run a per-frame pixel-art pass on every frame independently, the animation boils. The detected grid shifts a pixel one way, the palette shifts a shade the other way, and your character shimmers like a bad GIF from 1998. That's why the video half of this pack exists as its own node instead of "just loop the image node."

Why a separate node

Proper Pixel Art Video / GIF pixelates a whole animation with one shared grid and one shared palette. Upstream, the trick is that every frame of an animation sits on the same underlying mesh, so the expensive steps - Canny, morphological closing, Hough line detection, line clustering, width estimation, and palette quantization - are solved once over a sample of frames (num_sample_frames, default 8) and then applied to every frame. One grid, one palette, no frame-to-frame jitter. Same deterministic algorithm as the image node otherwise: no model, no checkpoint, no API key, CPU-friendly.

It's the same fix the community arrived at independently for AI pixel art in general: the model gives you the composition, a deterministic grid-detect-and-quantize pass gives you the pixels, and for animation the grid has to be solved globally or not at all.

Inputs that matter

  • input_path - a dropdown of video/GIF files from ComfyUI's input folder, with upload enabled on the widget itself, so dragging a file in drops it into input/ without any manual copying.
  • num_colors (default 0) - 0 keeps the dominant colors, 1–256 quantizes to a palette. For a GIF, always quantize; an unquantized animation balloons.
  • initial_upscale_factor (1–8, default 2) and pixel_width (0 = auto) - same meaning as on the image node. Raise the upscale factor or hard-code the width when detection misses.
  • scale_result (1–20, default 1) - integer nearest-neighbor upscale of the whole animation.
  • transparent_background - keys out the most common boundary color. Note the tooltip: GIF output supports binary transparency only, so you get hard-edged holes, not soft alpha.
  • num_sample_frames (default 8) - how many frames are sampled to solve the mesh and the palette. This cost is paid once, so pushing it up is cheap insurance on a long clip.
  • output_format - gif or mp4.
  • config (from the Config node) and intermediate_dir are optional, and intermediate_dir is again your best debugging lever.

Output

One output: output_path, a STRING holding the server-side path of the file written into ComfyUI's output directory. This node is flagged as an output node, so it runs and saves even if nothing is wired downstream - it's a terminal node, not something you chain into another image pipeline. The written file is named from the input plus the output dimensions, something like walkcycle_64x64.gif.

GIF or MP4?

MP4 is encoded near-losslessly - libx264 at CRF 1 - through PyAV, whose wheels bundle their own FFmpeg, so you don't need FFmpeg installed system-wide and quality doesn't depend on whatever your box happens to have. That's where the av dependency in the pack's requirements comes from. GIF output uses a single global palette for the whole animation.

Practical rule: MP4 if it's going anywhere near a video editor or a phone, GIF if it's a sprite-sheet preview or a forum post.

Install

ComfyUI Manager, search ComfyUI-ProperPixelArt, install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/unclepomedev/ComfyUI-ProperPixelArt
cd ComfyUI-ProperPixelArt
pip install -r requirements.txt

requirements.txt is just proper-pixel-art>=2.0.0,<3.0.0; the imaging stack (OpenCV headless, Pillow, NumPy, SciPy, PyAV) comes in transitively. The pack wants Python ≥3.12 and a reasonably new ComfyUI (it's built on the newer node API), and there are no model files to download.

Where people get burned

The dot in your output directory. The pack README flags this and it's real: upstream picks the container format from the suffix of the output path, and this node hands it ComfyUI's output directory. Point ComfyUI at a directory whose name contains a dot - output.v2, D:\comfy\output.old - and that dot gets read as a format name, which is one of the few ways this node fails outright.

input_path is empty. The combo only lists files in ComfyUI's input folder. Videos sitting in output/ won't show up; drag them into the node's upload widget or move them into input/.

Long clips feel slow. Detection samples frames, but every frame still gets snapped and quantized. Quantize down with num_colors, and keep scale_result at 1 until the look is right.

Nodes missing entirely. You're on a ComfyUI old enough that the pack's entry point never loads.

Categoryimage/Proper Pixel Art

Inputs (10)

NameTypeDefaultDescription
input_pathCOMBOSource video or GIF from the ComfyUI input directory.
num_colorsINT00–256Number of colors to quantize the frames to. 0 keeps dominant colors (preserves all colors), while 1 or more quantizes to that many colors using palette method.
initial_upscale_factorINT21–8Initial image upscale factor before grid detection. Useful if detected spacing is too large.
pixel_widthINT00–256Width of pixels in the input frames. 0 auto-detects pixel width.
scale_resultINT11–20Width of pixels in the output animation. 1 means no scaling.
transparent_backgroundBOOLEANfalseMakes pixels matching the most common boundary color transparent. GIF output supports only binary transparency.
num_sample_framesINT8Number of frames to sample for mesh and palette detection across the video or GIF.
output_formatCOMBOgifOutput container format for the video/GIF pipeline.
configoptCOMFYUI_PROPERPIXELART_CONFIGOptional advanced configuration overriding algorithm defaults.
intermediate_diroptSTRINGSubfolder in the ComfyUI output directory to save intermediate algorithm visualization images. Empty disables saving.

Outputs (1)

NameTypeDescription
output_pathSTRINGServer-side file path to the saved video or GIF in the ComfyUI output directory.