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!
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.