Skip to main content
IP

Image Palette Extractor

Extract dominant colours from any image — colour quantization, percentage breakdown, click-to-copy hex codes.

Did you like the tool? Thanks!
Share:

How to Use Image Palette Extractor

Upload an image and the tool analyses its pixel data to extract the most dominant colours using a simplified colour quantization algorithm. A slider lets you choose how many colours to extract (3–12, default 5). Each extracted colour is displayed as a swatch with its hex code, and a percentage bar shows approximately how much of the image that colour covers. Click any swatch to copy its hex code. Large images are scaled down for analysis to keep processing fast and responsive.

About Image Palette Extractor

Extracting a colour palette from an image — sometimes called colour quantization or palette generation — is the algorithmic process of taking an image that may contain thousands or millions of distinct colours and reducing it to a small, representative set that captures the visual essence of the original. This is the same problem solved by GIF encoders, vector quantization codecs, and numerous design tools that generate "colour themes" from photos. The brute-force approach — sort all pixels by frequency and take the most common exact colours — does not work well in practice because real-world photos contain colour noise, anti-aliasing at edges, and JPEG compression artifacts that create many near-identical but technically distinct pixel values. A pixel at RGB(200, 100, 50) and another at RGB(201, 101, 51) are perceptually indistinguishable, but a simple frequency count treats them as separate colours. The result is a "palette" of several hundred near-duplicate shades, not the handful of meaningfully different colours the user wants. This tool uses a simplified colour quantization approach based on binning in a reduced colour space. Instead of the full 24-bit RGB space (256³ = 16.7 million possible colours), the algorithm reduces each channel to 4-bit precision (16 levels), creating a 3D histogram with 16³ = 4096 bins. Each pixel in the sampled image is mapped to its bin by right-shifting each channel value by 4 bits (dividing by 16 and flooring). The bin counts are accumulated, and at the end the top N bins by pixel count are selected. For each of these top N bins, the algorithm calculates the average colour of all sampled pixels that fell into that bin — not the bin centre, but the actual arithmetic mean of the pixel values. This produces smoother, more representative colours than using the bin centres would. To keep the operation fast even on large images, the algorithm does not scan every pixel. A sampling stride (step) of 6 pixels is used in both the horizontal and vertical directions — meaning only roughly 1/36th of all pixels are examined. For a 12-megapixel photo (4000×3000), this means examining about 333,000 pixels instead of 12 million, which takes well under 100 milliseconds in JavaScript. The trade-off between speed and accuracy is negligible for palette extraction: missing a few pixels here and there does not change the dominant colour clusters. A slider control lets the user pick how many dominant colours to extract, from 3 to 12 (default 5). Each extracted colour is rendered as a swatch alongside a horizontal bar chart showing the percentage of sampled pixels that fell into that colour's bin — a rough measure of how much of the image that colour "covers." All swatches are clickable to copy the hex code, and a total coverage percentage shows how much of the total sampled pixels are accounted for by the displayed palette.

Details & Tips

Algorithm in detail: **Step 1: Load and scale the image.** The selected file is loaded via FileReader and drawn onto an offscreen canvas at the display size (capped at max 900px width, preserving aspect ratio). The canvas dimensions become the pixel sample space. **Step 2: Pixel sampling.** A nested loop iterates over the canvas pixels with a stride of 6 in both directions, calling `getImageData(x, y, 1, 1).data` at each sampled position. Each call returns `[R, G, B, A]`. Transparent or near-transparent pixels (alpha < 128) are skipped to avoid counting empty background areas. **Step 3: Build the 3D histogram.** For each sampled pixel, compute `binR = R >> 4` (i.e., `Math.floor(R / 16)`), and similarly for G and B. The bin index is `(binR << 8) | (binG << 4) | binB`, which packs three 4-bit values into a single 12-bit integer (0–4095). A `Map` or plain object accumulates two things per bin: the count of pixels in that bin, and two sums (totalR, totalG, totalB) for later average computation. For efficiency with 4096 possible bins, a plain object keyed by the index integer is used. **Step 4: Extract top N bins.** The histogram object is converted to an array of `{ index, count, totalR, totalG, totalB }` entries, sorted in descending order by count, and the first N entries are taken (N from the slider). **Step 5: Compute average colour per bin.** For each top bin entry, the average colour is `Math.round(totalR / count)`, etc. The result is converted to a hex string via `.toString(16).padStart(2, '0')`. The percentage coverage is `(count / totalSampledPixels) * 100`, rounded to one decimal place. **Display:** Each extracted colour is shown as a row containing a colour swatch (a small filled square), the hex code, a horizontal percentage bar (proportional to coverage), and the numeric percentage. The swatch acts as a button — clicking it copies the hex code via `navigator.clipboard.writeText()`. A Copy button next to each swatch also copies the hex. **Slider:** An `<input type="range" min="3" max="12" x-model="numColors">` slider with a numeric display. When the slider changes, steps 4-5 are re-run (the histogram need not be rebuilt). Debouncing is not required because sorting 4096 entries and rendering a handful of swatches is extremely fast. **Edge cases:** - Solid-colour image: the histogram has exactly one non-zero bin. The top N will include that bin plus N-1 zero-count bins. The tool displays only bins with count > 0, so it gracefully shows fewer swatches than N. - Very small images (e.g., 50×50 icons): the stride of 6 would sample too few pixels. The tool adapts: if either dimension is below 100px, the stride is reduced to 2 or 1 to ensure adequate sampling. - Animated GIFs: the browser renders only the first frame onto the canvas, so the palette is based on frame 1 only. **Performance:** For a 900×600 display canvas, the stride-6 sampling examines approximately (900/6)×(600/6) = 150×100 = 15,000 pixels. Each `getImageData` call reads 1 pixel. Modern engines handle this in under 20ms. The histogram binning and sorting are O(sampled_pixels + bins_log_bins) where bins is at most 4096, so also negligible. **Limitations:** - The binning approach with 4-bit channels groups similar but not identical colours. Very subtle gradients may spread across multiple bins, causing a few near-identical swatches to appear in the top N. This is inherent to the simplicity of the approach — a full median-cut or k-means algorithm would be more accurate but far more complex and slower in JavaScript. - The percentage bar reflects sampled pixel count, not perceptual area. A bright, saturated accent colour on a small object may have high visual prominence but low pixel count.

Frequently Asked Questions

How does the palette extractor work?
It samples pixels from the image, groups them into 4096 colour bins (4-bit per channel), counts how many pixels fall into each bin, sorts the bins by frequency, and extracts the average colour of the top N bins you selected via the slider.
Why not just count the most common exact pixel colours?
Real-world photos have JPEG artifacts, anti-aliasing, and noise that create millions of near-identical but technically distinct pixel values. Counting exact colours would give hundreds of nearly identical shades, not a useful palette. Binning groups similar colours together.
What does the percentage bar mean?
It shows what proportion of all sampled pixels fell into that colour's bin — a rough measure of how much of the image area that colour covers. It is approximate because the tool samples every 6th pixel, not every pixel.
How many colours can I extract?
Use the slider to choose between 3 and 12 colours. The default is 5, which works well for most photos — it captures the main theme colours without overwhelming detail.
Why does my image appear smaller after upload?
Images wider than 900 pixels are scaled down proportionally so they fit on screen. The palette is extracted from the displayed canvas, not the original file, but the dominant colours are preserved well at any reasonable display resolution.
Does the tool scan every single pixel?
No — it samples every 6th pixel in both directions (a stride of 6) for speed. For a typical 900×600 image, this means examining about 15,000 pixels instead of 540,000. The accuracy loss for palette generation is negligible.
What image formats are supported?
Any format your browser can render: JPEG, PNG, WebP, BMP, GIF, AVIF, and SVG. Animated GIFs are analysed based on their first frame only.
How do I copy a colour from the palette?
Click any colour swatch or its Copy button, and the 7-character hex code (with #) is copied to your clipboard. A "Copied!" confirmation appears briefly.
What happens if I upload a solid-colour image?
The tool will show only one swatch (or very few), since there is only one distinct colour in the image. It gracefully handles this — empty bins are simply not displayed.
What about transparent areas of PNG images?
Pixels with alpha below 128 (semi-transparent or fully transparent) are skipped during sampling so they do not influence the colour counts. The palette is based only on the opaque parts of the image.
Is my image uploaded anywhere?
No — the image is loaded entirely in your browser via the FileReader and Canvas APIs. No data leaves your computer.
How fast is the palette extraction?
For typical photos, the entire analysis (sampling, binning, sorting, rendering) completes in under 100 milliseconds — effectively instant from the user's perspective.

Part of These Collections

Also Available As

image palette extractor, dominant colors from image, color quantization, extract palette, image color analysis, color theme from photo, palette generator, image to palette

Found a Problem?

Let us know if something with Image Palette Extractor isn't working as expected.

Thanks — we'll take a look.