Understanding image colour
Pulling a palette from a picture.
How "dominant colour" gets computed, why it isn't the arithmetic mean, and what happens at the edges.
Average isn't dominant.
The naive way to summarise an image's colour is to average every pixel's RGB channels. Try that on a photo of a red apple on a white tablecloth and you get pink — the white background drowns out the actual subject. Real palette extraction algorithms cluster pixels into a small number of groups and pick a representative for each. The dominant colour is the centre of the largest cluster, not the average.
cluster pixels → centre of largest cluster
k-means in colour space.
The classic algorithm is k-means: pick k initial colours, assign each pixel to the closest one, recompute each centre as the mean of its assignments, repeat until nothing moves. For a 5-colour palette, set k = 5 and stop when the centres stabilise. Running it in OKLab rather than RGB gives clusters that match what the eye sees as similar — RGB distance treats blue-purple and red-purple as far apart even though they look almost identical.
Median cut is faster.
For real-time palette extraction in a browser, the median-cut algorithm is the practical choice. Treat the colour cube as a box of all the pixels, find its longest axis (red, green, or blue), split the box at the median value along that axis, and recurse until you have the desired number of boxes. Each box's average colour is one palette entry. It's fast, has no random initialisation, and produces good results for most images.
Sampling — you don't need every pixel.
A 4 megapixel photo has four million pixels. Running k-means on all of them is wasteful — clustering converges on a random 10,000-pixel sample to nearly the same answer in a fraction of the time. Most "instant palette" tools downscale to a thumbnail first, then cluster. The visual fidelity of the dominant colour doesn't suffer; the alternative would be a noticeable pause every time the image changes.
Picking a single pixel.
When the user clicks on the image to read the colour at a spot, you're sampling a single pixel — which has caveats. JPEG's chroma sub-sampling means adjacent pixels in saturated regions can have surprising values. Anti-aliased edges contain colours from neither side of the boundary. The honest fix: average a small box (3×3 or 5×5) around the click. The picked colour matches what the user thought they were pointing at.
Privacy by default.
Pixel sampling is one of the few image operations that's genuinely cheap and genuinely client-side. Every modern browser exposes the raw bytes of a loaded image via Canvas.getImageData, which means a colour picker doesn't need to upload anything. A photo dropped in stays in the browser; the palette comes back from the GPU. That's the right default for any image tool.
Read next