Color Gel Save
Downscale, quantize, and export in one pass
- image
- image
- file
- files_json
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) orpng. WebP gives you the lossless option; PNG is always lossless and mapscompression(1–100) onto Pillow's 0–9 compress level.resize_w/resize_h- 0 keeps original; set one and the other keeps aspect. Pair withresample: thepixelmode does block-averaging when the target divides evenly (1024→64 stays crisp, no blur between cells), falling back to area-average otherwise.lanczosis the default and fine for photos;pixelis the point of this node.reduce_palettewithreduce_palette_max_colors(default 32) - quantizes to a limited set.reduce_palette_method(mediancutdefault,fastoctree,maxcoverage) andreduce_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 ontoflatten_bg_color(#RRGGBBorr,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_DIRsomewhere sane or fix permissions. - Pixel edges look mushy on a 1024→64 downscale - you're on
lanczos, notpixel. The pack's own recommended preset for that job ispixelresample, sharpen ~1.5/0.5–1.0/0–4, reduce_palette on at 32 colors, posterize 5–6, andpalette_lock_across_batchfor tiles. - Names not used - you wired
names_packedbut leftuse_names_for_filenamesfalse. 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.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image (RGB/RGBA). | |
| filename | STRING | image | Base filename without extension. |
| save_as | COMBO | webp | Output format. |
| lossless | BOOLEAN | false | Lossless WebP (ignored for PNG). |
| compression | INT | 901–100 | WebP quality 1-100; PNG compression mapped 0-9. |
| reduce_palette | BOOLEAN | false | Reduce colors via quantization. |
| reduce_palette_max_colors | INT | 321–256 | Max colors after palette reduction. |
| save_opacity | BOOLEAN | true | Keep alpha channel; if False flattens on background color. |
| flatten_bg_color | STRING | #FFFFFF | Background color when save_opacity is False (hex or r,g,b). |
| resize_w | INT | 00–16384 | Resize width; 0 keeps original. |
| resize_h | INT | 00–16384 | Resize height; 0 keeps original. |
| resampleopt | COMBO | lanczos | Resize filter; 'pixel' does block-averaging to a fixed grid. |
| sharpenopt | BOOLEAN | false | Apply unsharp mask after resize. |
| sharpen_amountopt | FLOAT | 1.000–5 | Sharpen strength (mapped to 0-500%). |
| sharpen_radiusopt | FLOAT | 1.000–10 | Unsharp mask radius (pixels). |
| sharpen_thresholdopt | INT | 00–255 | Unsharp threshold (edge sensitivity). |
| use_names_for_filenamesopt | BOOLEAN | false | Use provided names as filenames for batches. |
| names_packedopt | STRING | Optional newline-separated names (one per image) used when saving a batch. | |
| overwriteopt | BOOLEAN | false | Overwrite existing files instead of suffixing (name(2), …). |
| optimize_pngopt | BOOLEAN | true | Use PNG optimizer (may be slower). |
| drop_metadataopt | BOOLEAN | true | Strip embedded metadata (EXIF/ICC) when possible. |
| reduce_palette_ditheropt | COMBO | none | Dither for palette reduction (fs/none). |
| reduce_palette_methodopt | COMBO | mediancut | Palette selection algorithm. |
| posterize_bitsopt | INT | 00–8 | Posterize RGB to N bits before palette reduction (0 disables). |
| palette_lock_across_batchopt | BOOLEAN | false | Derive palette from first image and reuse for all in the batch. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| file | STRING | — |
| files_json | STRING | — |