Why Most Color Pickers Are Wrong About 1 Pixel (and Why It Matters)
A color picker tells you the color of a single pixel. But a pixel is not a color — it is a sample of a continuous function, and the sample is usually wrong. Here is why, when it matters, and what to do about it.
A color picker samples one pixel of an image, but a pixel is not the color of the area — it is a sample of a continuous function, and the sample can be wrong. The most common sources of error: anti-aliasing at edges, sub-pixel rendering, dithering, JPEG compression, gamma correction, and color profile mismatches. The fix is to average a small area (3x3 or 5x5 pixels) instead of trusting a single pixel. The <a href="/color-picker">Color Picker</a> on this site does this automatically when you pick from an image — it samples a 5x5 area and averages.
You open a color picker, click on a pixel, and get a hex code. You paste the code into your CSS. The color you get is not the color you clicked on. This is not a bug. It is the fundamental nature of how digital images work, and most color pickers do not handle it correctly.
What a pixel is not
A pixel is not a color. A pixel is a sample of a continuous color function at one specific point. The image is a 2D function that maps (x, y) to a color value. The pixel at (x, y) is the value of that function at that point. It is not the value of the area around the point.
The distinction matters because of how the image was created. If the image was a photograph, the pixel values are samples of a continuous function that the camera captured (with some quantization). If the image was rendered from text or shapes, the pixel values are samples of a vector function that the renderer converted to pixels. In both cases, the pixel at any point is the function value at that point, not the average around it.
For a clean, sharp image, the pixels within a single feature (say, a red square) all have the same value. The color picker gives you the right answer. For an image with anti-aliasing, dithering, or compression, the pixels at the edge of a feature are a mix of the feature color and the adjacent color, and the pixel value is not the color of either. The color picker gives you the wrong answer.
The seven sources of error
The most common reasons a single-pixel color sample is wrong:
1. Anti-aliasing at edges
When a vector shape is rendered to pixels, the edges are anti-aliased — the pixels at the edge are a blend of the shape color and the background color. The blend is not a useful color; it is an artifact of the rendering. Sampling one of these pixels gives you a color that exists in the image but is not the color of any feature in the image.
For example, a black line on a white background, rendered with anti-aliasing, has gray pixels at the edges. Sampling one of the gray pixels gives you gray, not black or white. The actual color of the line is black; the actual color of the background is white. The gray pixel is neither.
2. Sub-pixel rendering
On displays with high pixel density (Retina, 4K), text and shapes are sometimes rendered at a sub-pixel level. The pixels at the edge of a character are not solid colors but blends of the channel values. Sampling these pixels gives a color that is not the intended color of the text or background.
This is a smaller effect than anti-aliasing but more common in modern UI screenshots. A color picked from a high-DPI screen may not match the CSS color the designer used.
3. Dithering
When an image is converted from a higher color depth to a lower color depth, dithering is used to preserve the appearance. Dithering introduces noise — the pixels in a "uniform" area have small random variations in color. Sampling one of these pixels gives a color that is not the underlying color.
This is most common in GIFs and in images that have been optimized for the web. The dithering pattern is a feature of the image, not the underlying color. To get the underlying color, you need to average the dithered pixels.
4. JPEG compression
JPEG is a lossy compression format. The compression introduces small errors in the pixel values, especially near edges and in high-contrast areas. The errors are usually 1-2 levels on a 0-255 scale — not visible to the eye but enough to throw off a color picker.
The effect is that a "pure red" pixel in a JPEG might be (255, 0, 0) in the source but (252, 1, 2) in the compressed image. The color picker gives you (252, 1, 2), not (255, 0, 0). The difference is small but noticeable in some uses.
5. Gamma correction
Images are stored in sRGB color space, which is gamma-corrected. A pixel value of 128 in sRGB is not 50% gray — it is about 22% gray in linear RGB. The color picker gives you the sRGB value, but most color calculations expect linear values. The difference is noticeable in color blending and image processing.
For most uses (picking a color for CSS), the sRGB value is what you want. For color processing (blending, comparison), you need to convert to linear first. Most color pickers do not do this conversion, which is correct for CSS but wrong for color science.
6. Color profile mismatches
Images can have different color profiles: sRGB, Adobe RGB, Display P3, ProPhoto RGB. The pixel values are interpreted differently in each profile. A pixel with value (255, 0, 0) is one red in sRGB, a different red in Adobe RGB, and a still different red in ProPhoto RGB. The color picker gives you the raw value, not the profile-corrected value.
For images that have a specific color profile embedded, the color picker should use that profile to interpret the value. Most color pickers ignore the profile, which gives the right answer for sRGB images and the wrong answer for everything else.
7. Display calibration
The pixel values in the image are the actual values. But the values displayed on your screen are modified by your display's color profile, brightness, contrast, and color temperature. The color you see is not the color that is in the image. The color picker reads the actual value, not the displayed value.
For most uses, this is fine. The CSS color you get from the picker is the actual color in the image. But if you are trying to match a color you see on the screen to a color in the image, the display mismatch means the colors will not match exactly.
How to pick a color correctly
The fix for the single-pixel problem is to average a small area instead of trusting a single pixel. The standard approach is to sample a 3x3 or 5x5 area and average the values. The average is the "true" color of that area, smoothed over the noise.
The averaging should be done in linear RGB, not sRGB. Two pixels with sRGB values (128, 128, 128) and (128, 128, 128) average to (128, 128, 128) in sRGB, but the average of two pixels with values (128, 128, 128) and (64, 64, 64) is not (96, 96, 96) in sRGB — it is more like (105, 105, 105) when the gamma correction is accounted for. The difference is small but real.
For most uses, the simple average in sRGB is close enough. The linear conversion is needed for color-accurate work (color science, image processing, color matching). For CSS, the sRGB average is fine.
How to pick a color from a specific area
If you want the color of a specific feature (a button, a background, a logo), the best approach is to find a "clean" area — a region that is unambiguously the feature color. For a button, this is the center of the button, away from any borders, text, or shadows. For a background, this is the area far from any other feature.
For a clean area, the single-pixel color is reliable. For an edge or transition, the single-pixel color is not reliable. The color picker should let you pick a small area and average, or let you pick from a clean area only.
Most color pickers do not do this. They let you click anywhere and report the pixel value. The result is a value that is somewhere in the image but not necessarily the color you wanted.
When does it matter
For most uses, the error from a single pixel is small and does not matter. If you are picking a background color and the difference between (240, 240, 240) and (245, 245, 245) is not important, the single-pixel sample is fine.
The error matters when the color has to match precisely. For a brand color, for a color that has to match a print or another display, or for a color that is at the edge of a feature, the single-pixel error is too large. In these cases, you need to average an area or pick a clean spot.
For most web and UI work, the precision is not critical and a single-pixel sample is fine. For design, print, and color-accurate work, the precision matters and you need a better approach.
How the color picker on this site handles it
The Color Picker on this site does two things to give you better results than a naive single-pixel sample:
- When you pick from an image, it samples a 5x5 area and averages the values. The average smooths over the noise and gives you the "true" color of the area.
- It reports the sRGB value, which is what CSS uses. If you need linear values for color processing, convert them yourself (or use a color science library).
The 5x5 average is a heuristic. For most images, it is enough. For images with severe dithering or compression, a larger area might be needed. The picker does not do this automatically; if you have a difficult image, sample a larger area manually or use a different tool.
The honest answer
A color picker gives you the value of one pixel of an image. The value is not the same as the color of the feature, because of anti-aliasing, dithering, compression, gamma, and color profile issues. To get the actual color, you need to average a small area or pick from a clean spot. The simple pick-a-pixel workflow gives an approximate answer, which is fine for most uses and not fine for color-accurate work.
The fix is to know the limitation. Sample multiple pixels. Average. Pick from clean areas. Use a color picker that does this for you. The picker on this site does the averaging. The picker in your design tool probably does not.
Once you know the limitation, you can work around it. The mistake is to assume the picker is exact and design based on a single sample. The pixel you sampled is not the color of the feature. It is a sample of a continuous function, and the function has been sampled in a way that is biased by the rendering, compression, and display chain.