99tools

Image Color Picker & Palette Extractor

runs in your browser

Pick any colour from an image and extract its dominant palette and Vibrant-style swatches on your device; export as CSS, Tailwind, SCSS, JSON or GPL.

Drop a file here, or .

A photo, screenshot or design. Read on your device; nothing is uploaded.

Sample

about this tool

Reading colours off an image

Drop a photo, screenshot or design. It is decoded onto a canvas in your browser at up to 1200 px on its longest side, and everything that follows works on those pixels; nothing is uploaded. Move over the image for a live reading — hex, rgb(), hsl(), the pixel coordinates, and the nearest of the 148 CSS colour names with a note on whether the match is exact — and click to keep a colour in the picked list, up to twelve, for copying singly or together. The sampler averages a 3 × 3 patch by default because single pixels in a JPEG are noisy; 1 px and 5 × 5 are a click away.

The palette

The dominant colours come from median cut, the algorithm behind colorthief and most palette tools: all sampled pixels begin in one box, the box with the widest range in any channel is split at its median along that channel, and this repeats until there are as many boxes as colours wanted. Median cut alone splits by pixel count, so a large area of one colour tends to be sliced through the middle; a few k-means passes seeded from the median-cut boxes move the boundaries onto the real clusters. Each cluster's mean is a palette colour, shown with its share of the image and drawn as a bar whose width is that share. Near-white pixels can be excluded, which helps with product shots and screenshots on white.

Pixels are sampled on a stride that keeps around twenty thousand in play, so the palette is instant and recomputes as you move the slider or the near-white switch — no library, no download.

Vibrant-style swatches

Six roles borrowed from Android's Palette API and Vibrant.js — vibrant, dark vibrant, light vibrant, muted, dark muted, light muted. Each palette colour is scored against a role's target saturation and lightness, weighted a little by how much of the image it covers; the best fit takes the role and is not reused. A role nothing fits stays empty, shown as a dashed square, rather than being filled with a poor match.

Export

CSS custom properties, a Tailwind v4 @theme block, SCSS variables, JSON (hex, rgb and share) and the GIMP palette format that GIMP, Inkscape and Krita import directly, all numbered from the most common colour down and named after the palette name you give.

Limits

The palette comes from a downscaled sample, so a hairline of colour covering a fraction of a percent of the image may not appear; raise the colour count or pick it by hand. Colours are treated in sRGB; wide-gamut images are converted by the browser on the way in. Averaging is in RGB, which is fine for small patches. Nothing is stored.

To convert a picked value between HEX, RGB and HSL, use the colour converter; to build a full scale from one of the extracted colours, the colour palette generator.

questions

How is the palette worked out?
By median cut, the algorithm behind colorthief and most palette tools: the image’s pixels start in one box, the box with the widest colour range is split at its median, and so on until there are as many boxes as colours wanted. A few k-means passes then move the boundaries onto the real clusters, which fixes median cut’s habit of slicing a big colour in half, and each cluster’s mean becomes a palette colour, with its share of the image.
What are the Vibrant-style swatches?
Six roles borrowed from Android’s Palette API and the Vibrant.js library: vibrant, dark vibrant, light vibrant, muted, dark muted and light muted. Each palette colour is scored by how close its saturation and lightness sit to the role’s target, weighted by how much of the image it covers, and the best fit takes the role. Roles nothing fits are left empty rather than filled with a poor match.
Why does the picked colour differ from the pixel I clicked?
By default the sampler averages a 3 × 3 patch, because JPEG noise and anti-aliasing make single pixels unreliable. Switch the sample to 1 px for the exact pixel, or 5 × 5 for a steadier average over textures. The reading also names the nearest of the 148 CSS colours and says whether the match is exact.
Is the image uploaded?
No. The file is decoded onto a canvas in your browser at up to 1200 pixels on its longest side and its pixels are read there; the palette, the swatches and the picker all work on that data. Nothing leaves the page and nothing is stored.
Which export should I use?
CSS variables or the Tailwind @theme block for a website, SCSS for a Sass project, JSON for code, and GPL for GIMP, Inkscape and Krita, which read that palette format directly. Every format numbers the colours from the most common down.