Image Palette Extractor
Extract the dominant colors from any image with share percentages, plus a pixel-exact eyedropper — entirely on this device.
Median cut groups the sampled pixels into boxes and reports each box's mean, so a swatch is an approximation of a region of the image, not a color that must appear in it.
Drop an image here — it is decoded on this device, never uploaded.
No drag and drop needed — the button opens this device's file picker.
PNG, JPEG, WebP, GIF, BMP or AVIF · up to 20 MB
You can also paste an image from the clipboard anywhere on this page — screenshots work.
On phones clipboard paste is limited — the picker button does the same job.
Drop, pick or paste an image — its dominant colors appear here.
Your image is decoded and measured inside this tab — open your network tab and check: nothing is uploaded. The same image, color count, sampling step, seed and matte always produce the same palette.
Press ? for shortcuts
Do it offline:$ magick photo.jpg -resize 25% -colors 6 -unique-colors txt:-
How to use it
- Drop an image on the pane, choose one with the button, or paste a copied image. The browser's own decoders handle PNG, JPEG, WebP, GIF, BMP and AVIF.
- Set the color count — 3 to 16 — and press Extract. The swatch rack reserves its rows first, so nothing jumps when the result lands.
- Copy one swatch, the palette as hex, rgb() or hsl() text, or CSS custom properties. Download writes the same list to a file.
- Switch to point pick for the eyedropper: click the preview, or move the crosshair with arrow keys and press Enter.
Drop a photo, screenshot or logo and read the colors that cover it: 3 to 16 swatches, each with the share of sampled pixels behind it, the image's average color, and an eyedropper for any single pixel. The pixels are quantized in this tab, so the file never leaves the device.
How it works
Extraction reads pixels, not the file: the image is drawn to a canvas and its RGBA bytes go to the quantizer. At 262,144 pixels or fewer, every pixel is read; above that, one in every N, and that step is printed, because a color covering fewer pixels than the step can be missed.
The quantizer is median cut, published by Paul Heckbert in 1982. Sampled pixels start in one box in RGB space; the box with the largest population times its longest channel range is cut at that channel's median, until there are as many boxes as colors asked for. Each box reports the mean of its pixels, so a swatch is often a value no pixel holds.
Alpha comes first: a fully transparent pixel has no color to report, so it is tallied and left out, and a partly transparent one is blended over the matte — white by default, editable. Both decisions are printed.
Examples
10 × 10 test image: 40 crimson, 30 sky, 20 green, 10 near-white pixels#e11d48 40.0% 40 px
#0ea5e9 30.0% 30 px
#16a34a 20.0% 20 px
#f8fafc 10.0% 10 px
average #7b778bFour flats far apart in RGB, so each lands in its own box and the shares are the proportions that went in. The average row is separate: the mean of all 100 sampled pixels, #7b778b.
Eyedropper on a 3 × 2 swatch: opaque, transparent, and alpha 128(0, 0) #0ea5e9
(2, 0) #ffffff N_TRANSPARENT_SKIPPED
(1, 1) #90e2ae N_MATTE_COMPOSITEDThe first pick is the stored byte triple. The second lands on a transparent pixel and reports the matte, #ffffff, rather than refusing. The third is alpha 128: #90e2ae over white, #196f43 over #101828.
64-pixel icon with a transparent background, 4 colors, matte #101828#0ea5e9 47.1% 16 px
#e11d48 23.5% 8 px
#0f5f89 17.6% 6 px
#facc15 11.8% 4 px
average #5c7d99
sampled 34 opaque of 64 pixels · 30 transparent skipped · 6 blended over #101828Shares are measured against the 34 pixels that had a color, not all 64. The swatch #0f5f89 exists only because six sky-blue pixels at alpha 128 blended over the dark matte.
800 × 400 two-axis gradient, 5 colors, stride left on auto#404040 25.3% 40,400 px
#c04040 25.0% 39,996 px
#c0c040 24.5% 39,204 px
#20bf40 12.8% 20,400 px
#61bf40 12.5% 20,000 px
average #7f8040
Sampled one pixel in every 2: 160,000 of 320,000 pixels were read. Probable cause: the image is larger than the 262,144-pixel sampling target, so the stride was chosen automatically — a smaller stride is more accurate and slower.A smooth gradient has no dominant colors, so median cut returns five region averages with nearly equal shares. The last line is the engine's stride note, verbatim.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Animated files contribute one frame
An animated GIF, WebP or AVIF decodes to its first frame, and that frame is what gets quantized.
Rotation moves the crosshair, not the palette
JPEGs with an EXIF orientation flag decode upright, so what you point at is what you sample. Reordering pixels changes no count anyway.
Everything is read back as 8-bit sRGB
Canvas data is four bytes per pixel, so a 16-bit PNG or Display-P3 photo arrives converted; browsers may disagree on an ICC-profiled JPEG.
Three caps, and each refusal names its limit
20 MB before decoding; 10,000 px per side and 33,554,432 pixels in total once the natural size is known.
Two runs of one image are byte-identical
Splits that could go either way are settled by a seeded generator, and the seed is a setting. Change the count, stride, seed or matte and the palette may change; change nothing and it cannot.
SVG input belongs elsewhere
Raster only: a vector file has no pixels until something picks a render size, and that choice would decide the answer.
Common errors
`20` is not a usable color count — probable cause: the count must be a whole number from 3 to 16; fewer than 3 is not a palette, and past 16 the colors stop being dominant ones.- The control cannot leave that range, but a shared link can carry an old value; restored counts clamp back with a notice.
The matte color was refused — `blurple` is not a valid color — expected hex (3/4/6/8 digits), rgb(), hsl(), oklch(), or a CSS color name. Probable cause: partly transparent pixels are composited over the matte before quantization, so the matte must be a CSS color your browser can parse.- The refusal carries the parser's own reason. Any CSS color the browser accepts works, and a matte's alpha is ignored.
Every sampled pixel is fully transparent — probable cause: the image is blank, or its only visible content was skipped by the sample stride, so there is no color to extract.- Usual causes: an empty export, a cropped-out subject, or a large hand-set stride over a mostly transparent sprite sheet.
Pixel (3, 1) is outside the 3 × 2 image — probable cause: the pointer position was not scaled from the displayed preview size back to the image's natural size.- The eyedropper works in image coordinates, so a half-size preview maps clicks back first. Keyboard picking stops at the edges.
The sampled pixels hold only 2 distinct colors, fewer than the 6 asked for — probable cause: a flat graphic or a screenshot of solid fills; the palette returns the colors that exist rather than inventing any.- A notice, not a failure: the palette comes back shorter than asked — flat logos and UI screenshots hit it routinely.
FAQ
How do I get the dominant color of an image?
Read the first swatch: the box median cut kept largest, with the share of sampled pixels behind it. Ask for 3 colors for a blunter answer.
Why does asking for more colors change the earlier swatches?
Each extra color is one more cut, and a cut replaces a box with two whose means differ from the parent's — so a 6-color palette is not a 4-color palette plus two.
What exactly do the percentages add up to?
They total 100% of the pixels sampled that had a color, not of the whole image; sampled, transparent and blended counts sit beside the result.
Does the picture get uploaded to a server?
No. The browser decodes it, this tab draws it to a canvas, and the buffer goes to a worker in the same tab — open the Network panel before dropping a file and see. Share links carry only settings.
Can I trust the eyedropper to be pixel-exact?
For an opaque pixel, yes: the stored bytes, no averaging or smoothing. Over a transparent pixel it reports the matte, over a partly transparent one the blend.