AnyTool
Your files never leave your device. All processing happens locally in your browser.

How do I extract a colour palette from a photo online for free without uploading it?

Open Color Palette from Photo, then drop, click-to-browse or PASTE an image. It is decoded into an offscreen canvas and its pixels are read entirely in your browser; a modified median-cut quantizer reduces them to the dominant colours, each shown with its hex, RGB, HSL, pixel share, nearest CSS colour name and WCAG contrast. A live eyedropper reads any exact pixel, and you can export a PNG swatch sheet, CSS variables, JSON, a GIMP .gpl or plain HEX / RGB / HSL lists. Nothing is uploaded.

  • Drop, browse or paste a PNG / JPG / WebP / GIF / BMP — it never leaves your device
  • Modified median-cut (volume × population) so a small vivid accent isn’t swallowed by a big region
  • 2–12 colours with hex / RGB / HSL, pixel share, nearest CSS name & WCAG contrast
  • Live on-image eyedropper for any exact pixel; one-tap copy of every value
  • Sort by dominance, hue or lightness; export PNG, CSS vars, JSON, GIMP .gpl, or HEX/RGB/HSL
  • 100% client-side — no upload, no server, no CDN, no tracking

What is

Color palette from photo (client-side dominant-colour extraction)

Extracting a colour palette from a photo means reducing the millions of pixel colours in an image to a small set of representative “dominant” colours. A client-side extractor does this entirely in the browser: the image is drawn to an HTML5 <canvas>, its RGBA pixels are read with getImageData, and a colour-quantization algorithm — here a modified median cut — clusters similar pixels and reports each cluster’s population-weighted average colour and its share of the pixels. Because a swatch is a cluster average rather than one exact pixel, the palette is a faithful approximation, and an eyedropper is provided for reading exact pixel colours.

Design

Related terms

dominant colourcolour quantizationmedian cutk-meanscolour paletteeyedropperhex coloursRGBWCAG contrastnearest named colourcanvas getImageData

Frequently Asked Questions

No. The image is decoded into an offscreen canvas and its pixels are read and clustered on your own device. There is no upload, no server, no CDN and no tracking, so the photo never leaves your browser.

Color Palette from Photo is 100% client-side. When you drop, browse or paste an image it is loaded into an in-memory HTML5 <canvas>; the tool reads its RGBA pixels with getImageData and runs the whole colour-quantization and eyedropper logic in the page. No bytes are sent to a server, there is no upload endpoint and no CDN in the processing path, and nothing is logged or stored. The tool works offline once cached, keeps no accounts and sets no tracking, and the image and palette are discarded the moment you close the tab.

It uses a modified median cut: the colour cube is repeatedly split along its longest axis, always splitting the box with the largest volume times pixel count, so a small vivid accent isn’t swallowed by one big region.

The pixels are quantized with a Bloomberg/Leptonica-style modified median cut. The full set of sampled colours is treated as one box in RGB space; the engine repeatedly splits the box along its widest colour axis at the median, but it always picks the box with the greatest priority — its colour-cube volume multiplied by how many pixels it holds. Weighting by population (rather than just colour range, as plain median cut does) keeps small but distinct clusters — a logo, a bright accent — from being merged into one huge near-uniform region such as a sky. Each final box’s swatch is its population-weighted average colour, and its share of the sampled pixels is reported as a percentage.

Each swatch is the average of a whole cluster of similar pixels, not one exact pixel, and the image is sampled at a capped size for speed. For an exact colour, use the eyedropper.

A palette is a summary: every swatch is the population-weighted average of a cluster of similar pixels, so it represents a range of the image rather than any single pixel — that is why a subtle accent can be masked by a large near-uniform region. For speed the image is also sampled at a capped long side of about 360px, so the palette is a faithful approximation rather than a per-pixel census. If you need one precise colour, move over the image with the built-in eyedropper, which reads the exact pixel (averaged over a tiny 3×3 window to shrug off JPEG noise); to surface more accents in the palette, raise the colour count.

Yes. Copy the palette as CSS variables, JSON, a GIMP/Inkscape .gpl file, or plain HEX / RGB / HSL lists, or download a labelled PNG swatch sheet — all generated on your device.

After extraction you can order the palette by dominance, hue (spectrum) or lightness, then export it several ways: a labelled PNG swatch sheet (each band shows the hex, pixel share and nearest CSS colour name), CSS custom properties (:root variables), a JSON array with hex/RGB/HSL and share, a GIMP palette (.gpl) that GIMP, Inkscape and Krita import directly, or plain HEX / RGB / HSL lists you can paste into professional design tools, Sketch or code. Every individual swatch and value is also one-tap copyable. All exports are produced locally — nothing is uploaded.

Detailed Explanation

How It Works

What Color Palette from Photo Does

Color Palette from Photo reduces the millions of pixel colours in an image to a small set of representative dominant colours, entirely in the browser. The user drops, browses or pastes an image; it is drawn to an offscreen HTML5 <canvas>, its RGBA pixels are read with getImageData, and a modified median-cut quantizer clusters similar pixels into 2–12 swatches. Each swatch reports its hex, RGB and HSL values, its share of the sampled pixels, the nearest CSS named colour, and its WCAG contrast against white and black. A live eyedropper reads any exact pixel under the pointer.

  • Input: PNG, JPG, WebP, GIF, BMP via drag-drop, file picker or clipboard paste
  • 2–12 dominant colours, each as a cluster average with a pixel-share percentage
  • Per-swatch hex / RGB / HSL, nearest CSS name, and WCAG contrast vs white & black
  • Live on-image eyedropper for exact pixel colours (3×3 averaged)
  • Export PNG swatch sheet, CSS variables, JSON, GIMP .gpl, or HEX/RGB/HSL lists
Methodology

Method: Modified Median-Cut Quantization

Pixels are quantized with a Bloomberg/Leptonica-style modified median cut. All sampled colours start as one box in RGB space; the engine repeatedly splits the box along its widest colour axis at the median, but it always splits the box with the greatest priority — its colour-cube volume multiplied by its pixel population. Weighting by population (not just colour range, as plain median cut does) prevents a large near-uniform region such as a sky from monopolising the palette and lets small, distinct clusters — a logo, a bright accent — stay represented. Each final box’s swatch is its population-weighted average colour; near-duplicate boxes are merged.

  • Split priority = colour-cube volume × pixel count (population-weighted)
  • Splits along the longest RGB axis at the channel median
  • Keeps small vivid clusters that plain median cut would merge away
  • Swatch colour = population-weighted average of the box
  • Near-duplicate boxes merged so no two identical swatches appear
Technical Details

Sampling, Colour Space and Named Colours

To stay fast on large photos, the image is rasterised with its long side capped at about 360px before sampling, and pixels are stride-sampled toward roughly 24k samples. Fully or mostly transparent pixels (alpha < 125) are skipped so the palette reflects visible colour, not the checkerboard behind a PNG. Colour maths (hex/HSL formatting, nearest-name matching in OKLab ΔE, WCAG contrast and hue sorting) uses the culori library, loaded lazily so the page shell and ads paint first. The eyedropper averages a 3×3 window around the pointer to reduce JPEG noise.

  • Long side capped at ~360px; stride-sampled toward ~24k samples
  • Transparent pixels (alpha < 125) skipped
  • Nearest CSS name via perceptual OKLab ΔE over 147 keywords
  • Sorting by hue uses OKLCH for a perceptually even spectrum
  • culori loaded lazily on first use; eyedropper 3×3-averaged
Limitations

Honest Limitations

A swatch is the average of a cluster of similar pixels, not one exact pixel, so a subtle accent can be masked by a large near-uniform region — raise the colour count or use the eyedropper for an exact value. Because the image is sampled at a capped size, the palette is a faithful approximation rather than a per-pixel census. Colours are read in sRGB, so a wide-gamut or colour-managed original may look slightly different in a print or design app, and JPEG chroma subsampling can nudge hues. The tool reads pixel colour as displayed; it does not correct white balance or infer an object&rsquo;s &ldquo;true&rdquo; colour under different lighting.

  • Swatches are cluster averages, not exact pixels (use the eyedropper for exact)
  • Capped sampling = approximation, not a per-pixel census
  • Read in sRGB; wide-gamut / colour-managed sources may differ on the target medium
  • JPEG chroma subsampling can shift hues slightly
  • No white-balance / true-colour correction — pixel colour only
Privacy & Security

Private by Design

Everything happens on the user&rsquo;s device. The image is decoded into an in-memory HTML5 &lt;canvas&gt; and its pixels are read and clustered locally with no upload endpoint, no server-side processing and no CDN in the path. The only optional network use is consent-gated ads; the image bytes, the extracted palette and any eyedropper reading never leave the browser. The tool works offline once cached, keeps no accounts, sets no tracking, and discards the image and palette the moment the tab is closed.

  • Image decoded to a local <canvas>; pixels read with getImageData on-device
  • No upload, no server-side processing, no CDN in the extraction path
  • Palette, PNG, CSS, JSON and .gpl exports all generated locally
  • Works offline once cached; no accounts, no tracking
  • Image and palette discarded on tab close
Colour-quantization approaches for extracting a palette from a photo
MethodHow it worksTrade-offUsed here
Modified median cutSplit the box with the largest volume × pixel countFast; keeps small vivid accents representedYes
Plain median cutSplit the box with the widest colour rangeFast, but a big flat region can dominateNo
K-means clusteringIteratively move K centroids to cluster meansCan be more faithful but slower and init-dependentNo
Frequency histogramBucket colours and pick the most common binsSimple, but merges perceptually distinct coloursNo

All run client-side on stride-sampled pixels; the eyedropper reads exact pixels directly. As of July 2026.