Please bookmark this page to avoid losing your image tool!

Image Color Picker

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg) {
    const mainContainer = document.createElement('div');
    mainContainer.style.display = 'inline-block';
    mainContainer.style.border = '1px solid #eee'; // Optional: add a light border to the whole tool
    mainContainer.style.padding = '10px';
    mainContainer.style.borderRadius = '4px';

    const canvas = document.createElement('canvas');
    canvas.style.cursor = 'crosshair';
    canvas.style.display = 'block'; // Prevents extra space if container is block/inline-block
    canvas.style.maxWidth = '100%'; // Make canvas responsive if its container is smaller
    canvas.style.height = 'auto';   // Maintain aspect ratio with maxWidth
    
    // Optimization hint for frequent getImageData calls
    const ctxOptions = { willReadFrequently: true };
    const ctx = canvas.getContext('2d', ctxOptions);

    const colorInfoContainer = document.createElement('div');
    colorInfoContainer.style.marginTop = '10px';
    colorInfoContainer.style.display = 'flex';
    colorInfoContainer.style.alignItems = 'center';
    colorInfoContainer.style.fontFamily = 'Arial, Helvetica, sans-serif';
    colorInfoContainer.style.fontSize = '14px';
    colorInfoContainer.style.minHeight = '22px'; // Ensure consistent height even if text is empty

    const pickedColorLabel = document.createElement('span');
    pickedColorLabel.textContent = 'Picked Color: ';
    pickedColorLabel.style.marginRight = '4px';

    const colorPreview = document.createElement('div');
    colorPreview.style.width = '20px';
    colorPreview.style.height = '20px';
    colorPreview.style.border = '1px solid #333';
    colorPreview.style.backgroundColor = 'transparent'; // Initial state
    colorPreview.style.marginRight = '8px';
    colorPreview.style.boxSizing = 'border-box';

    const colorText = document.createElement('span');
    // Initial placeholder text set by loading logic

    colorInfoContainer.appendChild(pickedColorLabel);
    colorInfoContainer.appendChild(colorPreview);
    colorInfoContainer.appendChild(colorText);

    mainContainer.appendChild(canvas);
    mainContainer.appendChild(colorInfoContainer);

    function byteToHex(byte) {
        return byte.toString(16).padStart(2, '0').toUpperCase();
    }

    function drawMessageOnCanvas(message, isError = false) {
        const MSG_CANVAS_WIDTH = 300;
        const MSG_CANVAS_HEIGHT = 100;

        // If canvas drawing surface is not the standard message size, resize it.
        if (canvas.width !== MSG_CANVAS_WIDTH || canvas.height !== MSG_CANVAS_HEIGHT) {
            canvas.width = MSG_CANVAS_WIDTH;
            canvas.height = MSG_CANVAS_HEIGHT;
        }
        
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = isError ? '#fff0f0' : '#f8f8f8'; // Light red for errors, light gray for info
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        ctx.fillStyle = isError ? '#c00000' : '#555'; // Dark red for error text, dark gray for info text
        ctx.textAlign = 'center';
        ctx.font = '14px Arial, Helvetica, sans-serif';
        
        const fontSize = parseInt(ctx.font, 10) || 14;
        const yPos = canvas.height / 2 + fontSize / 3; // Approximate vertical centering
        ctx.fillText(message, canvas.width / 2, yPos);
    }
    
    function setupInteraction() {
        canvas.addEventListener('click', function(event) {
            // Check if image is ready and no critical errors occurred (like CORS)
            if (!originalImg || !originalImg.complete || originalImg.naturalWidth === 0 || canvas.dataset.pickerError) {
                // Update info text if not already an error message
                if (!canvas.dataset.pickerError) {
                    colorText.textContent = "(Image not ready. Cannot pick color.)";
                }
                // If there's a pickerError, it message is already likely set from drawMessageOnCanvas
                return;
            }

            try {
                const rect = canvas.getBoundingClientRect();
                // Calculate click coordinates relative to the canvas element's display size
                let x = event.clientX - rect.left;
                let y = event.clientY - rect.top;

                // If canvas is scaled via CSS (style.width/height different from attribute width/height),
                // adjust click coordinates to match the canvas's internal backing store resolution.
                if (canvas.clientWidth !== canvas.width || canvas.clientHeight !== canvas.height) {
                    const scaleX = canvas.width / canvas.clientWidth;
                    const scaleY = canvas.height / canvas.clientHeight;
                    x *= scaleX;
                    y *= scaleY;
                }
                
                // Ensure coordinates are integers and within the canvas bounds
                x = Math.floor(x);
                y = Math.floor(y);

                if (x < 0 || x >= canvas.width || y < 0 || y >= canvas.height) {
                    // Click was outside actual image bounds on canvas (e.g. due to rounding or if canvas is larger than image)
                    return; 
                }

                const pixelData = ctx.getImageData(x, y, 1, 1).data;
                const r = pixelData[0];
                const g = pixelData[1];
                const b = pixelData[2];
                const a = pixelData[3] / 255; // Alpha normalized to 0.0 - 1.0

                const hexColor = `#${byteToHex(r)}${byteToHex(g)}${byteToHex(b)}`;
                const rgbaColor = `rgba(${r}, ${g}, ${b}, ${a.toFixed(2)})`;

                colorPreview.style.backgroundColor = rgbaColor;
                colorText.textContent = `HEX: ${hexColor} | RGBA: ${rgbaColor}`;

            } catch (e) {
                if (e.name === 'SecurityError') {
                    const securityErrorMsg = 'Cross-origin security error.';
                    colorText.textContent = `(${securityErrorMsg})`;
                    drawMessageOnCanvas(securityErrorMsg, true); // Show error on canvas too
                    canvas.dataset.pickerError = securityErrorMsg; // Mark canvas as errored
                } else {
                    colorText.textContent = '(Error picking color.)';
                    console.error("Error picking color:", e);
                    // Optionally draw this error on canvas too if it's persistent
                }
            }
        });
    }

    function drawImageAndSetup() {
        delete canvas.dataset.pickerError; // Clear any previous error state on new draw attempt

        if (!originalImg || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
            const emptyMsg = 'Image is empty or invalid.';
            colorText.textContent = `(${emptyMsg})`;
            drawMessageOnCanvas(emptyMsg, true); // True for error styling
            canvas.dataset.pickerError = emptyMsg; // Mark canvas as errored
            return;
        }

        canvas.width = originalImg.naturalWidth;
        canvas.height = originalImg.naturalHeight;
        
        // Clear canvas before drawing new image (in case it's transparent and parts of old message show through)
        ctx.clearRect(0,0,canvas.width, canvas.height); 
        ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
        
        // Update text if it was a status message
        const currentText = colorText.textContent.trim();
        if (currentText.startsWith('(') && currentText.endsWith(')')) {
             colorText.textContent = '(Click on the image to pick a color)';
        } else if (currentText === '') { // if it was empty for some reason
            colorText.textContent = '(Click on the image to pick a color)';
        }
    }
    
    // --- Initialization ---
    colorText.textContent = '(Loading image...)';
    drawMessageOnCanvas('Loading image...'); // Initial message on canvas
    setupInteraction(); // Setup click listener structure once. Handler checks image readiness.

    if (originalImg.complete && originalImg.naturalWidth !== undefined) { 
        // Image is already loaded (or failed to load but 'complete' is true)
        // naturalWidth check for safety, though 'complete' usually implies it's set.
        drawImageAndSetup();
    } else {
        originalImg.onload = () => {
            drawImageAndSetup();
        };
        originalImg.onerror = () => {
            const errorMsg = 'Error loading image.';
            colorText.textContent = `(${errorMsg})`;
            drawMessageOnCanvas(errorMsg, true);
            canvas.dataset.pickerError = errorMsg; // Mark as errored
        };
        // If originalImg.src is not set, 'load' or 'error' might not fire.
        // 'complete' might be true and naturalWidth 0, handled by the 'if (originalImg.complete)' block.
        // If src is set but invalid and browser doesn't fire error for some reason:
        // this scenario is less common but could lead to 'Loading...' indefinitely.
        // Most modern browsers robustly fire 'error' for invalid src.
    }

    return mainContainer;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Color Picker tool allows users to interactively select and extract color information from an uploaded image. By clicking on any point within the image displayed on the canvas, users can obtain the color values in both HEX and RGBA formats. This tool is useful for graphic designers, web developers, and artists who need precise color details for their projects or digital artworks. Whether for creating color palettes, designing websites, or simply exploring color options, this color picker facilitates easy identification of desired colors directly from images.

Leave a Reply

Your email address will not be published. Required fields are marked *