Nodes/Color Gel Pixel/Color Gel Save
ComfyUI Node

Color Gel Save

Downscale, quantize, and export in one pass

By cadric·Created 11 months ago·Updated 11 months ago· 0
Color Gel Save
  • image
  • image
  • file
  • files_json
filenameimage
save_aswebp
losslessfalse
compression90
reduce_palettefalse
reduce_palette_max_colors32
save_opacitytrue
flatten_bg_color#FFFFFF
resize_w0
resize_h0
resamplelanczos
sharpenfalse
sharpen_amount1.00
sharpen_radius1.00
sharpen_threshold0
use_names_for_filenamesfalse
names_packed
overwritefalse
optimize_pngtrue
drop_metadatatrue
reduce_palette_dithernone
reduce_palette_methodmediancut
posterize_bits0
palette_lock_across_batchfalse

Color Gel Save is the workhorse of the pack - the node you actually export through. It's a PNG/WebP saver with a genuine pixel-art personality: resize with a dedicated pixel-block mode, palette reduction with dithering control, posterize, unsharp sharpen, and alpha flattening all happen right here before the file hits disk. If you're producing sprites, tilesets, or any retro-leaning output, this is the node that turns "an AI image that kind of looks pixelated" into an actual artifact with a real palette.

The community position on pixel art is worth internalizing here: diffusion models do not produce pixel art - they produce soft, off-grid, full-color images. The real artifact comes from a deterministic post-process: downscale to a grid, quantize to a limited palette, optionally dither. Color Gel Save bundles that whole pipeline into one node. It's the "cheap deterministic primitive before the expensive generative one" idea from the KB's post-processing playbook, wrapped in a save dialog.

The inputs that matter

You get a lot of knobs, but four decisions cover 90% of use:

  • save_as - webp (default) or png. WebP gives you the lossless option; PNG is always lossless and maps compression (1–100) onto Pillow's 0–9 compress level.
  • resize_w / resize_h - 0 keeps original; set one and the other keeps aspect. Pair with resample: the pixel mode does block-averaging when the target divides evenly (1024→64 stays crisp, no blur between cells), falling back to area-average otherwise. lanczos is the default and fine for photos; pixel is the point of this node.
  • reduce_palette with reduce_palette_max_colors (default 32) - quantizes to a limited set. reduce_palette_method (mediancut default, fastoctree, maxcoverage) and reduce_palette_dither (none/fs) control how it's done. Floyd–Steinberg dithering is how you fake extra shades without banding.
  • save_opacity - true keeps alpha; false flattens onto flatten_bg_color (#RRGGBB or r,g,b, default white). If you're exporting tiles that must not have transparency, this is the control.

Beyond those: sharpen (unsharp mask, tuned by sharpen_amount/sharpen_radius/sharpen_threshold), posterize_bits (banding control before quantization), optimize_png, drop_metadata (defaults true - strips EXIF/ICC), and overwrite (default false, so existing files get name(2) suffixes instead).

The batch story is where it shines. Feed it a batch and it writes one file per frame - indexed as base_timestamp_0001.ext - or, with use_names_for_filenames + names_packed from Color Gel Names (N), named directly from your tints. palette_lock_across_batch derives one palette from the first frame and reuses it for the whole batch, which is exactly what you want for a tileset that has to stay color-consistent.

Outputs

  • image - a preview of exactly what was saved (RGB/RGBA).
  • file - absolute path of the last saved file.
  • files_json - a JSON array of every path written.

Files land in ComfyUI/output (override with the COMFYUI_OUTPUT_DIR env var).

Installing Color Gel Pixel

Save is part of the Color Gel Pixel pack (MIT, by cadric).

cd ComfyUI/custom_nodes
git clone https://github.com/cadric/color_gel_pixel

Restart ComfyUI, or ComfyUI Manager → Install Custom Nodes → "Color Gel Pixel." No models to download; pyproject.toml declares zero dependencies beyond torch/NumPy/Pillow, which ComfyUI already has. Needs ComfyUI 0.3.65+.

Common issues

  • "Output directory not writable" - Save checks it can write before saving. If you see this, point COMFYUI_OUTPUT_DIR somewhere sane or fix permissions.
  • Pixel edges look mushy on a 1024→64 downscale - you're on lanczos, not pixel. The pack's own recommended preset for that job is pixel resample, sharpen ~1.5/0.5–1.0/0–4, reduce_palette on at 32 colors, posterize 5–6, and palette_lock_across_batch for tiles.
  • Names not used - you wired names_packed but left use_names_for_filenames false. That switch is the whole deal.
  • Batch count vs names mismatch - named frames use their names, the rest fall back to numbered names. Keep them in sync if you want a clean folder.

This pack is young and quiet - don't expect a big community write-up behind it. What you get is a tightly-scoped, deterministic saver that happens to encode the correct pixel-art pipeline, and for that it's genuinely hard to beat.

CategoryColor Gel Pixel/Core

Inputs (25)

NameTypeDefaultDescription
imageIMAGEInput image (RGB/RGBA).
filenameSTRINGimageBase filename without extension.
save_asCOMBOwebpOutput format.
losslessBOOLEANfalseLossless WebP (ignored for PNG).
compressionINT901–100WebP quality 1-100; PNG compression mapped 0-9.
reduce_paletteBOOLEANfalseReduce colors via quantization.
reduce_palette_max_colorsINT321–256Max colors after palette reduction.
save_opacityBOOLEANtrueKeep alpha channel; if False flattens on background color.
flatten_bg_colorSTRING#FFFFFFBackground color when save_opacity is False (hex or r,g,b).
resize_wINT00–16384Resize width; 0 keeps original.
resize_hINT00–16384Resize height; 0 keeps original.
resampleoptCOMBOlanczosResize filter; 'pixel' does block-averaging to a fixed grid.
sharpenoptBOOLEANfalseApply unsharp mask after resize.
sharpen_amountoptFLOAT1.000–5Sharpen strength (mapped to 0-500%).
sharpen_radiusoptFLOAT1.000–10Unsharp mask radius (pixels).
sharpen_thresholdoptINT00–255Unsharp threshold (edge sensitivity).
use_names_for_filenamesoptBOOLEANfalseUse provided names as filenames for batches.
names_packedoptSTRINGOptional newline-separated names (one per image) used when saving a batch.
overwriteoptBOOLEANfalseOverwrite existing files instead of suffixing (name(2), …).
optimize_pngoptBOOLEANtrueUse PNG optimizer (may be slower).
drop_metadataoptBOOLEANtrueStrip embedded metadata (EXIF/ICC) when possible.
reduce_palette_ditheroptCOMBOnoneDither for palette reduction (fs/none).
reduce_palette_methodoptCOMBOmediancutPalette selection algorithm.
posterize_bitsoptINT00–8Posterize RGB to N bits before palette reduction (0 disables).
palette_lock_across_batchoptBOOLEANfalseDerive palette from first image and reuse for all in the batch.

Outputs (3)

NameTypeDescription
imageIMAGE
fileSTRING
files_jsonSTRING