Image Color Picker and Palette Extraction, Explained

After reading this you will know how a pixel color is read from an image, how HEX, RGB and HSL describe the same color, and how median-cut quantization reduces millions of pixels to a small palette you can copy.

What the tool does and one quick example

An image is a grid of pixels. Each pixel stores three numbers for its red, green and blue channels, and often a fourth for opacity. The color picker reads those numbers at the exact point you hover, then reports the color in three notations at once. The palette extractor scans every pixel and reduces the whole image to a handful of representative colors.

Take a screenshot of a blue button. Hover over its center and the loupe might read #2563EB, which is rgb(37, 99, 235), which is hsl(217, 83%, 53%). Three strings, one color. The palette pass on the same screenshot might return that blue plus the white background, the dark text, and two shades of border gray. That is enough to rebuild the design in CSS.

When to use it, and when not

Reach for the picker when you need the true value of a specific pixel: matching a brand color, copying a shade from a mockup, or checking whether two regions are actually identical. Reach for the palette when you want the overall color story of a photo or UI: a set of swatches for a theme, a mood board, or a chart color scheme.

Do not use a single picked pixel to describe a textured region. A brick wall has hundreds of distinct pixel values, so one sample tells you almost nothing about the whole. For that question you want an average or a dominant color, not one point. Also avoid picking colors off a JPEG at high zoom and trusting them to the last digit, because JPEG compression shifts values by a few units near edges.

Everything runs in your browser. The image is decoded to a canvas locally, and no pixel data leaves your machine.

How a color is encoded: RGB, HEX and HSL

Each of the three channels holds an integer from 0 to 255, so a color needs 24 bits and there are 256^3 = 16{,}777{,}216 possible values. RGB writes those three integers directly. HEX writes each channel as two hexadecimal digits, so 235 becomes EB and the blue above is #2563EB.

HSL is the same color in different coordinates: hue as an angle, saturation and lightness as percentages. The conversion starts by scaling each channel to the range [0, 1], then finding the largest and smallest of the three.

L = \frac{\max(r,g,b) + \min(r,g,b)}{2}

Here r, g and b are the channels scaled to [0, 1], and L is lightness. A value of L = 0 is black and L = 1 is white. Saturation uses the spread between max and min: when they are equal the color is gray and saturation is 0. Hue is the angle of the dominant channel, 0 degrees for red, 120 for green, 240 for blue.

How the palette is built: median-cut quantization

Listing every distinct color would give you thousands of near-duplicates. Median cut solves this by treating each pixel as a point in a 3D box whose axes are red, green and blue. The algorithm repeatedly splits the box until it has as many boxes as the palette size you asked for, then returns the average color of each box.

  1. Put all pixels into one box spanning the full RGB range they occupy.
  2. Find the channel with the largest spread. If red ranges over 200 levels but green and blue only over 40, split on red.
  3. Sort the pixels in that box by the chosen channel and cut at the median, so half the pixels go to each new box.
  4. Repeat on whichever box currently has the widest channel spread, until you reach the target number of boxes.
  5. Average the pixels inside each final box to get one swatch.

Splitting at the median rather than the midpoint is the key idea. It puts the cut where the pixels actually are, so dense clusters get their own boxes and near-empty regions do not waste a swatch. A photo that is 70% sky still yields distinct swatches for the small bright objects, because those clusters get subdivided once the large sky box is split off.

Ask for a few more swatches than you think you need, then delete the ones that look redundant. Extracting 8 and keeping 5 gives a better result than extracting exactly 5, because the extra cuts separate colors that a coarse split would merge.

A worked example with the demo image

Splitting a four-color block into a two-color palette

Consider a tiny image with just four pixels so you can follow every step by hand:

The four source pixels
PixelRGB
A2030200
B4050210
C2206030
D2407050
  1. Range on red is 240 - 20 = 220. On green it is 70 - 30 = 40. On blue it is 210 - 30 = 180. Red is widest, so split on red.
  2. Sort by red: 20, 40, 220, 240. The median cut sends A and B to one box, C and D to the other.
  3. Average the blue box: red (20+40)/2 = 30, green (30+50)/2 = 40, blue (200+210)/2 = 205. That is rgb(30, 40, 205), or #1E28CD.
  4. Average the red box: red (220+240)/2 = 230, green (60+70)/2 = 65, blue (30+50)/2 = 40. That is rgb(230, 65, 40), or #E64128.

Two swatches, each the center of a real cluster. Notice that neither swatch matches any single source pixel exactly, which is expected: a swatch summarizes a group.

The two swatches sit at the center of their clusters: 30 for the low-red pair, 230 for the high-red pair.

Explore how palette size changes the result

With a palette size of 2 the four demo pixels split once on red into swatches near rgb(30,40,205) and rgb(230,65,40). With a palette size of 4 each pixel becomes its own swatch, so the palette reproduces the source exactly. Larger sizes never merge colors; they only subdivide.

Reading and interpreting the results

Copy the notation that fits the job. Use HEX or RGB for CSS and design files. Use HSL when you want to reason about the color: to darken a button, drop the lightness by 10 percentage points and keep hue and saturation fixed. Two colors with the same hue and saturation but different lightness are a natural pair for a shade ramp.

For a palette, judge the swatches by coverage, not by beauty. A good palette is one where laying the swatches over the image leaves few pixels far from any swatch. If a bright accent in the photo has no matching swatch, raise the palette size until the split that isolates it happens.

Channel
One of the red, green or blue values, an integer from 0 to 255.
Quantization
Replacing many colors with a smaller fixed set, here by median cut.
Loupe
The magnified square that shows individual pixels under the cursor so you can aim precisely.

Common mistakes

Trusting a single pixel on a compressed image. JPEG stores color in 8x8 blocks and averages chroma, so a pixel near a sharp edge can be off by 5 to 15 units. Sample a flat interior region, or pick from a PNG when accuracy matters.

Confusing a picked color with a dominant color. The picker reads one point. If you want the color that covers the most area, that is a different calculation.

Assuming the palette contains exact image colors. Each swatch is an average of a cluster, so it usually equals no single pixel. That is by design.

Anti-aliased text and thin lines mix foreground and background within one pixel. If you pick a black letter on white and get #7A7A7A, you hit a blended edge pixel, not the ink. Move to the thickest part of a stroke.

Related tools

To find the single color that best summarizes an image rather than a set of swatches, use Dominant & Average Color. To confirm two regions or two files are truly identical pixel for pixel, use Image Diff. To read camera settings or strip location data from a photo before sharing it, use EXIF Viewer & Remover. To pull text out of a screenshot, use Image OCR.

Frequently asked questions

Why does the same color show three different codes?

HEX, RGB and HSL are three notations for one color. #2563EB, rgb(37, 99, 235) and hsl(217, 83%, 53%) all describe the identical pixel. Pick whichever your target format uses.

How many swatches should a palette have?

For a UI theme, 5 to 8 covers background, text, and a few accents. For a photo mood board, 6 to 10. More than about 12 usually produces near-duplicate swatches that add no information.

Why does a swatch not match any pixel exactly?

Each swatch is the average of all pixels in one box. In the worked example the blue swatch was rgb(30, 40, 205), which is the mean of pixels A and B, not either one of them.

Can the picker read transparency?

Yes. A fourth channel, alpha, runs from 0 (fully transparent) to 255 (fully opaque). Over a transparent area the reported RGB is the stored pixel color, which may differ from what you see on the page background.

Does zooming change the color I pick?

The loupe magnifies for aim but reads the original pixel grid, so the value does not change with zoom. What changes is your accuracy in hitting the pixel you meant.