Color Extractor from Image

Pull the dominant colour palette from any image, with swatches, CSS variables and a matching gradient — processed entirely in your browser.

Or drop an image anywhere on this panel. Nothing is uploaded — the pixels are read in your browser.

The palette is read from about three thousand pixels

The extractor scales the longest side down to 64 pixels before it counts anything, which is what makes it instant. It also means a twelve-megapixel photograph is judged on 3,072 pixels — 0.026% of the picture.

ImageRead asPixelsShare of the original
4000 × 3000 (12 MP) 64 × 48 3,072 0.026%
1920 × 1080 64 × 36 2,304 0.111%
800 × 600 64 × 48 3,072 0.640%
64 × 64 64 × 64 4,096 all of it

Every image ends up at roughly the same pixel count, so a bigger photo does not get a better-sampled palette — only a sparser one. Anything already under the cap is read whole. That is fine for what a palette is for, and not fine for finding a colour that occupies a small part of the frame: a red jumper filling 2% of a large photograph survives as about 61 pixels, already averaged with its surroundings by the downscaler. It will not appear, and nothing will tell you it was considered.

Colours are grouped 4,096 at a time, then averaged

Each channel is cut to its top four bits, so 16.7 million possible colours collapse into 4,096 buckets holding 4,096 colours each. (The two numbers matching is a coincidence of cubing 16 and cubing 256/16.) Two colours 16 apart in one channel are always in different buckets; two colours one apart usually are not, but can be, if the boundary falls between them.

The averaging is the part worth noticing. Each bucket reports the mean of everything in it, which need not be a colour that appears in the image at all: a bucket holding equal amounts of rgb(16, 16, 16) and rgb(31, 31, 31) reports rgb(24, 24, 24), which is in neither. Sorting by bucket size then means the palette is ordered by how much of the frame a colour covers, which is usually the background rather than the subject.

And the duplicate filter measures distance in the wrong space

Near-duplicates are dropped when the sum of their channel differences is under 60 — plain arithmetic on red, green and blue, with no regard for how the eye weights them. Since green carries about 72% of perceived brightness and blue about 7%, a 59-step move in blue is nearly invisible and the same move in green is not.

PairFilter distanceVerdictContrast between them
    two greens 59 merged 2.21:1
    two yellows 60 kept 1.00:1

One step of distance separates those two rows, and the verdicts come out backwards: the visibly different greens are treated as one colour while the two yellows nobody could tell apart are both kept. The merged pair is 2.2 times more different than the pair that survived. Transparency is handled the same blunt way: pixels below alpha 128 are skipped entirely and everything at or above it counts in full, with no partial weighting in between.

None of this makes the tool wrong. It makes it a fast approximation, which is what a palette extractor should be. It is worth knowing which corners were cut, because between them they explain every surprising result it will ever give you.

How to use

  1. Upload an image, or drop one onto the page.
  2. Choose how many colours you want extracted.
  3. Review the swatches and adjust the count until the palette is useful.
  4. Crop to the region you care about if the whole image gives muddy results.
  5. Copy the palette as hex values, CSS variables, or a matching gradient.

Frequently asked questions

Does my image get uploaded anywhere?

No. The image is read and analysed entirely in your browser, so photographs never leave your device. That matters for personal images, for client work under an agreement, and for anything you hold under licence.

How does the extraction actually work?

By clustering the image's pixels into groups of similar colour and taking a representative from each group. The usual method is k-means clustering, which is why you choose how many colours to find — that number is the cluster count, and different values can produce noticeably different palettes from the same picture.

Why is my palette mostly muddy browns?

Because averaging across a varied photograph tends toward mud, particularly with foliage, mixed skin tones or uneven lighting. Increasing the colour count, or cropping to the region you actually care about, usually recovers something more usable.

Does the dominant colour mean the most eye-catching one?

No, and this is the most frequent misunderstanding. Dominant means most frequent by pixel count, which is almost always a large background area such as sky or wall. The colour that draws the eye is often a small saturated accent barely represented in the count at all.

Can I use these colours for text?

Not without checking contrast first. Extracted colours are chosen for how much of the image they occupy, not for legibility, and photographic colours cluster in the mid-tones — the worst range for carrying text against either a light or a dark background.

What is this actually useful for?

Building a design around a photograph, generating a matching background or gradient behind a hero image, theming a card from its own thumbnail, and identifying colours in a reference image for design or paint matching.

Why do the swatches change when I re-run it?

Because clustering starts from randomly chosen seed points, so successive runs can settle on slightly different groupings, particularly when several colours are close together. The broad palette stays stable; the exact hex values may shift a little.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.