Skip to tool
ecech.
🖼️ Image & Photo Tools

Dominant Colour Extractor That Clusters Instead of Averaging

Averaging the pixels of a red flower on green leaves gives brown. This groups pixels into real clusters, in linear light, so every colour you get is one you can see.

Advertisement

How the calculation works

An image that is half red and half green the input Average #945B35 a brown that is nowhere in the picture Cluster #C81E2D   #1E7A3C both colours, each 50% The mean of a distribution with two peaks sits in the valley between them.

How to Use This Tool

Drop in an image. You get the colours that are actually in it, how much of the image each one covers, and a contrast reading so you know which ones you can put text on.

Why not just average the pixels

Because an average assumes there is one thing to be average of. A photograph of a red flower on green leaves has two populations of pixels, and the mean of the two lands between them — a brown that appears in neither the flower nor the leaves. It is a correct calculation of a quantity nobody wanted.

Clustering asks a different question: what groups do the pixels fall into? Each returned colour is then the centre of a real group, which is why every swatch you get can be found somewhere in the image.

Median cut, and why the colours have a share

The method is median cut. Put every pixel in one box in colour space, find the axis along which the box is widest, split it at the median, and repeat on whichever box is now largest until you have as many boxes as you asked for. Each box becomes one palette entry.

Because the split is at the median rather than the midpoint, the boxes end up holding comparable numbers of pixels rather than comparable volumes of colour space. That is what makes the percentages meaningful — a colour covering 40% of the image is genuinely 40% of the pixels.

Linear light, and the reason blends look dark

The bytes in an image file are gamma-encoded: the value 128 is not half the light of 255, it is about 22% of it. Averaging those bytes directly is averaging the wrong numbers, and the result comes out noticeably too dark. This is the same bug behind the familiar complaint that a 50% blend between two colours looks muddy in most software.

So every average here is taken in linear light and converted back afterwards. It is two extra lines and it is the difference between a colour you would use and one you would reject.

Blending pure red and pure green, two ways #808000 averaging the bytes #BCBC00 averaging the light Same two inputs, same 50/50 mix. One of them is doing arithmetic on the encoding rather than the colour.
Gamma encoding is not linear, so the mean of two encoded values is not the mean of two colours.

The near-white and near-black option

Most photographs contain a lot of very light and very dark pixels — sky, shadow, paper, a product shot's background. They are real, and they will dominate the palette, and they are almost never what you were looking for. The filter drops pixels above 96% and below 6% lightness. Turn it off when the image is genuinely monochrome, or when the background colour is the thing you want.

What the contrast numbers mean

Each swatch shows its best contrast ratio against black or white. 4.5:1 is the WCAG AA threshold for normal text and 3:1 for large text. A colour that clears neither is a background for images, not for words.

Advertisement

Frequently Asked Questions

Why does averaging an image's pixels give a muddy colour?
Because an average has one answer and most images have several colours. The mean of a red flower on green leaves lands between the two, producing a brown that appears in neither. The arithmetic is right; the question was wrong. Clustering asks which groups the pixels fall into instead, so every result is a colour actually present.
What is median cut?
A way of dividing colour space into as many boxes as you want colours. All pixels start in one box; you find the axis along which it is widest, split at the median, and repeat on whichever box is largest. Splitting at the median rather than the midpoint means each box holds a comparable number of pixels, which is what makes the percentages meaningful.
Why does averaging colours in linear light matter?
Because image bytes are gamma-encoded — the value 128 carries about 22% of the light of 255, not 50%. Averaging the encoded values averages the wrong numbers and produces a result that is visibly too dark. This is the same reason 50% blends look muddy in a lot of software.
Is my image uploaded anywhere?
No. It is read with the browser's FileReader and drawn to a canvas in the page. Nothing is transmitted, which also means the tool works with the network off.
Why should I ignore near-white and near-black pixels?
Because sky, shadow, paper and studio backgrounds are usually the largest regions in a photograph and almost never the colour you were looking for. Leaving them in will hand you white and black as your two dominant colours, which is true and useless. Turn the filter off when the background is the thing you want.
Why does the same image give slightly different results at different colour counts?
Because each additional split subdivides an existing box, so asking for six colours does not simply add one to the five — the box that gets split changes which centres are computed. Colours that stay stable as you increase the count are the ones genuinely dominant in the image.

Related tools in Image & Photo Tools

Browse all Image & Photo Tools tools
The Mac mini the ecech. site is built on, beside a handwritten note reading ecech.com.

Made by one person

ecech. is not a content farm. Every tool here is written and checked by hand, one at a time, by someone who wanted the tool to exist and could not find a version that showed its working.

No accounts and no sign-in, and nothing you type reaches a server — every calculation on this page runs inside your browser. The ads are served by Google and do set their own cookies, which is set out in full on the privacy page. More about the site.