1001Ferramentas
🎨 Generators

Image Color Palette Generator

Upload an image and extract 3 to 24 dominant colors via k-means clustering. Export as HEX, RGB, CSS variables or Tailwind.

Paleta Extraída


      

      

      

      

Algoritmo: k-means (até 10 iterações). Pixels reduzidos para max 64k para performance.

Image-to-palette extraction: algorithms, colour spaces and dominant-vs-vibrant tradeoffs

"Pull the colours out of this picture" sounds trivial — the picture is made of colours, after all. In practice, decent palette extraction is one of the more interesting applied-clustering problems on the modern web. The naive answer (count pixels, return the top N) produces dull palettes dominated by sky-blue and skin-tone background. The interesting answer trades pure dominance for perceptual prominence: a small but saturated accent often beats a sea of muted background pixels. Google's Material You, Apple's Photos auto-tint, Spotify's album-art canvas effect and every IDE theme generator since 2017 wrestle with the same tradeoff.

Algorithm zoo

  • K-means — pick K random centroids, assign each pixel to the nearest, recompute the mean, repeat. Cheap (~50 ms on a 1000×1000 image), but sensitive to the random seed
  • K-means++ — smarter centroid initialisation (Arthur & Vassilvitskii 2007); better palettes for the same K, identical runtime
  • DBSCAN — density-based clustering, you do not specify K; great for photos with an unknown number of dominant colours
  • Mean shift — converges to local density modes; produces fewer but more representative colours
  • Octree quantisation — used by GIF/PNG encoders since the 1990s; deterministic, very fast
  • Median cut — Heckbert's 1980 algorithm, still the basis of color-thief and node-vibrant

Why colour space matters

RGB Euclidean distance is the default but is perceptually flawed — equal numeric jumps look unequal to the human eye. CIELAB (1976) was designed for perceptual uniformity: a Delta E under 2.3 is roughly the just-noticeable difference. OKLab (Björn Ottosson, 2020) corrects CIELAB's hue-shift artefacts and is what modern CSS Color 4 uses for oklch(). Running k-means in OKLab instead of RGB produces palettes that feel much closer to what a designer would pick by eye — at the cost of two extra colour-space conversions per pixel. Material You uses OKLab internally; node-vibrant still uses HSL for backward compatibility.

// Pseudocode: weighted prominence score
score(pixel) = saturation(pixel) * 0.5
             + frequency(pixel) * 0.3
             + centerProximity(pixel) * 0.2

Preprocessing tricks that actually matter

  • Downsample first — k-means on a 100×100 thumbnail gives essentially the same palette as the full image at 1/100th the cost
  • Gaussian blur — kills JPEG noise that would otherwise produce phantom centroids
  • Saturation weighting — multiply each pixel's weight by its HSV saturation so grey backgrounds lose against bright accents
  • Center bias — products and subjects sit in the centre of frame; weight central pixels higher
  • Edge masking — Sobel-filter the image and skip pixels on hard edges; removes anti-aliasing artefacts

Where it ships in production

Material You (Android 12, 2021) reads the user's wallpaper and generates a five-tonal-palette theme via the open-source material-color-utilities library. Spotify Canvas matches the looping video's dominant hue to the player UI. Apple Photos auto-tints the now-playing screen on iOS using palette extraction. ColorMind (2017) was an early RNN-based approach that learned designer palettes — it produces more aesthetic but slower output than pure clustering. On the web, color-thief, node-vibrant and the Canvas-API-based extractors all run in a Web Worker so the UI thread stays responsive during the 50–100 ms extraction.

FAQ

Dominant or vibrant — which should I return? Depends on the use case. UI theming wants vibrant (Material You picks the most saturated swatch as primary). Reporting "the colour of this product photo" wants dominant. Best practice: return both and let the consumer pick.

How fast is extraction in the browser? Under 100 ms for a 1024×1024 image with k-means on a downsampled 100×100 thumbnail. Direct extraction on the full image is 1–3 seconds and unnecessary.

Are AI-based extractors better than k-means? They produce more aesthetic, designer-like palettes (ColorMind, Khroma, Coolors) but cost cloud inference. For deterministic, offline, fast results, k-means++ in OKLab is the modern sweet spot.

Why does my palette include grey? Because grey backgrounds dominate pixel count without dominating perception. Add saturation weighting (skip pixels with saturation under 0.15) to fix it.

Related Tools