Extract Palette

Turn any photo into a palette, with the numbers and the files you need to use it.

Runs on your deviceImagesWorkingNo account needed

What this tool does

Extract Palette decodes your image onto a canvas, walks it at a fixed stride collecting pixels that are at least half opaque, and groups those samples into the number of colours you asked for. An image under roughly 48,000 pixels is read in full; above that the stride grows in whole pixels, which lands the sample somewhere between 24,000 and 48,000 of them. Each group comes back as HEX, RGB and HSL, alongside its share of the pixels that were read and the closest match from a short built-in list of names.

There are two ways of doing the grouping and they answer different questions. Median cut splits the colour space into boxes along each box's widest axis, choosing what to split next by both spread and population, so a small area of strong colour survives more often than it does under the alternative; every sampled pixel ends up in some box, so those shares add up to the whole. Most used slices each channel into fixed blocks of sixteen values and ranks the blocks by how many samples fall in them, which favours what dominates — but two shades one step apart still separate when a block boundary runs between them, and anything outside the top few blocks is dropped, so its percentages do not total 100. Median cut also cuts at an obvious gap when it finds one rather than always at the median, which stops two clearly separate colours being averaged into a third that appears nowhere.

Three things are worth knowing before you trust a swatch. Every colour returned is the mean of a cluster, so a HEX code may not correspond to any single pixel in the photo — for the literal value of one point use Image Color Picker, and for the single strongest colour use Dominant Color. The percentages are measured over the pixels that were sampled, and with the neutral filter on they are measured over whatever survived it, not over the whole frame. And the stride counts pixels in reading order rather than stepping across rows and columns, so when the width divides into it neatly — 4000 × 3000 gives a stride of 500, 6000 × 4000 a stride of 1000 — the samples land on as few as six or eight vertical lines, and a narrow upright feature between them is never seen at all. Decoding, sampling and grouping all run in this browser tab, so the image is not uploaded, and once the page has loaded the work carries on with the network off.

The results panel shows the swatches with their hex codes, a table, and the three files below it. No palette is kept between runs: a result is not stored, not set against a previous one, and not reorderable by hand, and there is no way to pin a colour you like and re-run for the rest.

How to use it

  1. Choose one image. Any format your browser can decode — JPG, PNG, WebP, GIF and usually AVIF. One file per run, read straight from disk into the page, and an animated GIF is measured from a single frame rather than the whole animation.
  2. Set how many colours you want. The slider runs from 2 to 16 and starts at 6. More colours means finer distinctions; fewer means a palette you can actually use.
  3. Pick median cut or most used. Median cut for a spread that covers the whole picture. Most used when you want the colours that occupy the most area, in order.
  4. Skip the neutrals if they are winning. This checkbox is off to begin with. Turning it on drops pixels below 12% saturation, above 94% lightness or below 6% — enough to take a white studio background out of the running before it claims the top swatch.
  5. Take the result away. A table of HEX, RGB, HSL and share, plus three downloads: palette.json, a palette.css declaring --palette-1 upward, and a PNG swatch sheet named after your file, four cells to a row.

Processing & privacy

Runs on your device. Your file is processed directly in this browser.

Common use cases

Theming a site around its hero image

The palette.css download is already a :root block of custom properties, so the colours can be dropped into a stylesheet without retyping any hex codes.

Choosing chart colours that match a photograph

Median cut returns a spread rather than six variations of the same blue, which is what a series of bars or lines needs to stay readable.

Pulling brand colours out of a product shot

Turn on the neutral filter so the white backdrop does not take the first three swatches, and the product's own colours come out on top.

Sanity-checking how prominent a colour really is

The share column is counted rather than guessed, so an accent you thought carried the picture can turn out to be under two per cent of the pixels that were read.

Handing a colour scheme to someone else

Each cell of the PNG sheet carries its uppercase hex value and its position in the palette, which makes it something you can paste into a document or a message as-is.

Questions

Does the photo leave my browser?
No. Decoding, sampling and quantisation all happen in this tab through the canvas API. Neither the image nor the palette is transmitted or stored anywhere, which is why an open page keeps working after the connection drops.
Why is a colour in the palette not in my photo?
Because each swatch is the average of a group of similar pixels, not a pixel that was picked out. That average usually sits inside the cluster, but on a gradient or a noisy photo it can land between two shades that both exist while it does not.
Which method should I choose?
Median cut for a palette that tries to represent the whole image, since it weighs how far a group of colours spreads and not only how many pixels it holds. Most used to see what actually covers the picture — it will happily return several near-identical shades when the image is genuinely made of them.
Why did I get fewer colours than I asked for?
Because the image did not contain that many distinguishable ones. A flat two-tone logo cannot be split into sixteen groups, so median cut stops when there is nothing left to divide rather than inventing swatches to fill the count, and most used can only return as many blocks as the samples actually occupy.
Does it look at every pixel?
Only on a small image. Below about 48,000 pixels every sufficiently opaque one is read; beyond that the stride widens so that roughly 24,000 to 48,000 are kept, which is what keeps a large photograph fast. The cost is the sampling caveat above: a small or narrow region of unique colour can be stepped over completely.
How are transparent images handled?
Pixels with an alpha value under 128 — a little under half opaque — are skipped. Those at or above it are counted at their own colour, without being blended against any background, so a semi-transparent overlay contributes its raw value rather than the colour you see on screen.
Are the colour names official?
No. Each swatch is matched to the nearest of thirty-five common names by plain RGB distance, with no perceptual colour space behind it. It is a label to help you talk about the swatch, not a standard — treat the HEX value as the real answer.

Related tools