Skip to main content
IC

Image Color Picker

Pick any pixel colour from an uploaded image — zoom lens, live HEX/RGB/HSL, lock colour on click.

Did you like the tool? Thanks!
Share:

Hover over the image to sample colours. Click to lock/unlock the picker. Locked

Zoom Lens

How to Use Image Color Picker

Upload an image and hover or click on any pixel to extract its exact colour. A magnified zoom lens shows a pixel-level preview around your cursor with a crosshair at the centre, so you can precisely target individual pixels. The picked colour is displayed as a large swatch with its HEX, RGB, and HSL values. Click to lock the colour — it stops updating on mouse move — and click again to unlock. A copy button lets you grab the hex code instantly. All processing happens in your browser.

About Image Color Picker

Colour-picking from an image is a surprisingly common task that ranges from casual ("what hex code is that beautiful sunset?") to professional ("what brand colour did my competitor use in their hero banner?"). While desktop applications like Photoshop and GIMP have an eyedropper tool built in, the web browser — where we spend an increasing amount of our working day — historically offered no such ability beyond picking from the page's own CSS. Browsers have since gained the `<input type="color">` element and the EyeDropper API (which is still Chrome-only as of mid-2025), but neither lets you load an arbitrary local image and sample arbitrary pixels without first uploading it somewhere. This tool fills that gap entirely client-side. You select an image file from your local disk using the standard file input. The image is drawn onto an HTML5 Canvas element that is capped at a maximum display width of 900 pixels — larger images are scaled down proportionally so they fit on screen without forcing horizontal scrolling, but the pixel-sampling logic uses coordinates relative to the displayed canvas, which maps exactly to the visual pixels you see. When you hover over the canvas, the tool reads the single pixel under your cursor using `getImageData(x, y, 1, 1).data`, which returns a `Uint8ClampedArray` of four values: red, green, blue, and alpha. The first three are directly the 8-bit channel values of the displayed pixel. The zoom lens is a small, separate canvas that renders a magnified preview of the region around your cursor. Every time the mouse moves, the tool reads a 10×10 pixel block centred on the cursor position using `getImageData()`, then draws that block scaled up by a factor of 10 onto the zoom canvas — so each source pixel becomes a 10×10 block of the same colour, creating a pixel-level magnifier. A crosshair (two perpendicular lines in a contrasting colour) marks the centre pixel. This makes it possible to target individual pixels even on a high-resolution image displayed at a fraction of its native size. Locking the colour is a quality-of-life feature: once you have found the exact colour you want, clicking the canvas toggles a lock flag. When locked, mouse movement no longer updates the picker — the swatch and all value displays remain frozen at the locked colour. Click anywhere on the canvas again to unlock and resume live sampling. The lock state is indicated visually (the canvas cursor changes and a small lock icon appears next to the swatch).

Details & Tips

Technical implementation: **Image loading and scaling:** The file input's `@change` event reads the selected file using `FileReader.readAsDataURL()`. A new `Image` object is created, and once its `onload` fires, the image is drawn onto the main canvas. The scaling logic preserves aspect ratio: `scale = Math.min(1, maxDisplayWidth / img.width)`. The canvas dimensions are set to `Math.round(img.width * scale)` × `Math.round(img.height * scale)`, and `ctx.drawImage(img, 0, 0, canvas.width, canvas.height)` renders the scaled image. This ensures the canvas bitmap matches what the user sees — there is no mismatch between the displayed pixel grid and the sampled coordinates. **Pixel reading:** On each `@mousemove` event (when not locked), the cursor position relative to the canvas is computed using `canvas.getBoundingClientRect()` and `event.clientX`/`clientY`. The coordinates are floored to the nearest integer pixel. The call `canvas.getContext('2d').getImageData(x, y, 1, 1).data` returns a 4-element array `[R, G, B, A]`. Channels are already clamped to 0-255 by the canvas API, so no additional clamping is needed. The alpha channel is ignored (since images drawn with `drawImage` are always fully opaque on the canvas unless the source image had an alpha channel — in practice, JPEG files have no alpha, and PNG files with transparency will show the alpha; the tool reads the RGB as displayed on canvas, which for transparent areas would show the canvas's default black background). **Zoom lens:** A separate small canvas (e.g., 150×150 pixels) acts as the zoom preview. When the mouse moves, the tool extracts a 15×15 pixel region centered on the cursor using `getImageData(cx-7, cy-7, 15, 15)`. The zoom canvas is cleared and the 15×15 block is rendered scaled up by 10× using `ctx.putImageData()` on an intermediate canvas first, then `ctx.drawImage()` with `imageSmoothingEnabled = false` to get blocky pixel-perfect scaling. A crosshair is drawn as two 1-pixel lines: one horizontal and one vertical through the centre, in an inverted colour (computed as `255 - R, 255 - G, 255 - B` of the centre pixel) for maximum visibility. **HEX/RGB/HSL display:** The picked colour's RGB values are converted to a 6-digit hex string using `.toString(16).padStart(2, '0')` and to HSL using the standard RGB-to-HSL formulas (normalise to 0-1, compute max/min, derive hue from the dominant channel with offsets of 0, 2, or 4, lightness from (max+min)/2, saturation from the difference divided by (1 - |2L-1|)). All three formats are displayed simultaneously. **Copy behaviour:** Clicking the Copy button next to the hex value triggers `navigator.clipboard.writeText(hexString)`. On success, the button text changes to "Copied!" and resets after 2 seconds via `setTimeout`. **Lock/unlock:** A boolean `locked` flag in the Alpine state controls whether `@mousemove` updates the colour. Clicking the canvas toggles `locked`. When locked, the cursor on the canvas changes to `cursor: crosshair` (or a custom lock cursor) to indicate the locked state. The picked colour display shows a small lock icon (🔒 text or an SVG). **Error handling:** If the selected file's MIME type does not start with `image/`, an inline error message is shown and no canvas drawing occurs. If the `Image.onerror` handler fires (e.g., corrupt file), an error is also shown. The error uses the standard inline error pattern: `<p x-show="error" x-cloak class="mt-3 rounded-lg border border-red-200 bg-red-50 px-4 py-2 text-sm text-red-600" x-text="error"></p>`. **Performance:** Canvas `getImageData()` is fast for single-pixel reads. The zoom lens reads a 15×15 block — 225 pixels — which is well within the performance budget even on older hardware. No debouncing is needed on mouse move; Alpine's DOM updates are batched by the browser's microtask queue. The image is only read once during the file input phase; subsequent interactions are all canvas reads, not image re-decodes. **Use cases:** Extracting brand colours from a competitor's screenshot, sampling a colour from a photo to use in CSS, building a mood board palette, checking if two images use the same shade, identifying the exact colour of a product in a catalogue image.

Frequently Asked Questions

How do I pick a colour from an image?
Upload an image using the file input, then hover your mouse over any pixel on the canvas. The colour values (HEX, RGB, HSL) update live as you move. Click to lock the colour at its current value.
What image formats are supported?
Any image format your browser can render — JPEG, PNG, GIF, WebP, BMP, SVG (rasterised), and AVIF. The file input accepts all typical image MIME types.
How does the zoom lens work?
A 15×15 pixel region around your cursor is extracted from the canvas and rendered 10× larger on a separate zoom canvas, with each source pixel becoming a 10×10 block. A crosshair marks the exact centre pixel.
What does "lock" mean?
Clicking the canvas toggles a lock. When locked, the colour swatch and all displayed values freeze — they stop updating as you move the mouse. Click again to unlock and resume live sampling.
Why does my large image appear smaller on the canvas?
Images wider than 900 pixels are scaled down proportionally to fit the page, with the aspect ratio preserved. The pixel you click on the scaled display maps exactly to the corresponding pixel in the scaled canvas bitmap.
How is the pixel colour read?
The canvas API's `getImageData(x, y, 1, 1).data` returns the red, green, blue, and alpha values of the single pixel at the cursor coordinates. This is a built-in, zero-cost operation in all modern browsers.
Can I pick colours from transparent areas of a PNG?
When the image is drawn onto the canvas, transparent areas render as the canvas default background (which is fully transparent black). The alpha channel is present in `getImageData()` output, but the tool displays the RGB values as they appear visually on the canvas.
Is the colour display in real time?
Yes — the HEX, RGB, and HSL values, swatch, and zoom lens all update on every mouse-move event over the canvas, providing effectively instantaneous feedback.
How do I copy the picked colour?
Click the Copy button next to the hex value. The 7-character hex string (with #) is copied to your clipboard. A "Copied!" confirmation appears briefly.
Is my image uploaded to a server?
No — the image is loaded entirely in your browser using the FileReader API and drawn onto a local canvas. Nothing is transmitted anywhere.
What happens if I try to upload a non-image file?
An inline error message appears: "Please choose an image file." The canvas is cleared, and no further action is taken.
Can I use this tool offline?
Yes — once the page is loaded, all processing is done client-side via JavaScript and the Canvas API. No internet connection is required.

Part of These Collections

Also Available As

image color picker, color picker from image, eyedropper tool, image color sampler, pick hex from image, pixel color picker, zoom lens color picker, image to hex

Found a Problem?

Let us know if something with Image Color Picker isn't working as expected.

Thanks — we'll take a look.