Nodes/ComfyUI Ideogram Palette and Prompt Tools/Ideogram Masked Palette Extractor
ComfyUI Node

Ideogram Masked Palette Extractor

The Palette of Just the Subject, Not the Whole Frame

By SurrealByDesign·Created 2 months ago·Updated 2 months ago· 3
Ideogram Masked Palette Extractor
  • image
  • mask
  • palette_json
  • palette_preview
  • color_count
num_colors8
min_delta_e10.0
mask_threshold0.50

The plain palette extractor looks at the whole image. That's a problem the moment your subject is a small part of a busy frame: a red jacket worn by a figure standing in front of a green field produces a palette that's mostly greens, and the jacket's red - the color you actually want to match - drowns. IdeogramMaskedPaletteExtractor only extracts colors from the pixels inside a mask, so you get the palette of the subject, not the scene.

This is the node that makes per-element palettes actually accurate. Ideogram 4's compositional_deconstruction schema lets each region of a generation carry its own reference palette, and a region-accurate palette is what makes that regional control read as intentional instead of random. Mask the subject → get its true colors → feed them to the element builder. The pack's showcase workflow showcase_04_masked_subject_and_global.json does exactly this: masked extraction for the per-element palette, plain extraction for the global one, two palettes in one structured prompt.

Inputs and how it works

The pipeline underneath is the same k-means + Delta-E (perceptual LAB distance) extraction as the rest of the pack, but the pixel pool is restricted to the masked region before clustering runs. Inputs:

  • image - the source IMAGE.
  • mask - a MASK, from any of ComfyUI's many masking/sampling nodes.
  • num_colors - 2 to 16, default 8.
  • min_delta_e - 0 to 100, default 10.0. Perceptual distance floor between kept colors.
  • mask_threshold - 0.0 to 1.0, default 0.5. Pixels with mask values above this count as "in the region."

Outputs: palette_json, palette_preview (swatch strip), color_count.

The mask_threshold input is the subtle one. Masks are grayscale, and a soft-edged mask from a blur or a SAM segmentation has no crisp boundary. The threshold decides where "in" becomes "out." Lower it and you include more of the feathered edge; raise it and you tighten toward the mask's bright core. If your palette keeps picking up background colors, your threshold is too low.

The graceful-failure behavior you'll appreciate

An empty or below-threshold mask - the classic footgun when a mask node produced nothing - doesn't crash. The node falls back to a single gray #808080 swatch and keeps the graph running. Annoying if it happens silently, but far better than a bricked workflow. If you ever see a one-color gray palette where a rich one should be, the mask is your first suspect.

Installing it

Same pack, same install. ComfyUI Manager: search "Ideogram Palette and Prompt Tools". Or:

cd ComfyUI/custom_nodes
git clone https://github.com/SurrealByDesign/ComfyUI-Ideogram-Palette-and-Prompt-Tools

Restart ComfyUI. Only extra dependency: scikit-learn (Manager installs it from requirements.txt, or pip install scikit-learn). torch/numpy/Pillow deliberately not pinned - ComfyUI already ships them, and the author won't risk a torch reinstall breaking your CUDA setup. Nodes under Ideogram/Palette, Python ≥ 3.10, tested on ComfyUI 0.24.0 / Python 3.12.

Gotchas and troubleshooting

  • Mask and image must be the same resolution. A resized or padded mismatch silently changes which pixels get selected. If the palette looks wrong, check the mask dimensions first.
  • Gray fallback = empty mask. Verify the mask node actually output something (PreviewImage it) before debugging the extraction itself.
  • Small regions give small palettes. A tiny subject with a handful of distinct colors may return fewer than num_colors - that's the dedup working, and for a ≤5-color element palette that's usually fine.
  • This is a regional tool, not a whole-frame one. If you have no mask, the plain IdeogramPaletteExtractor is the node you want; don't reach for this one and fight with thresholding for no reason.
CategoryIdeogram/Palette

Inputs (5)

NameTypeDefaultDescription
imageIMAGE
maskMASK
num_colorsINT82–16
min_delta_eFLOAT10.00–100
mask_thresholdFLOAT0.500–1

Outputs (3)

NameTypeDescription
palette_jsonSTRING
palette_previewIMAGE
color_countINT