You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, colorCount = "5") {
const count = parseInt(colorCount, 10) || 5;
const container = document.createElement('div');
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.alignItems = 'center';
container.style.fontFamily = '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif';
container.style.backgroundColor = '#fdfdfd';
container.style.padding = '20px';
container.style.borderRadius = '10px';
container.style.boxShadow = '0 6px 16px rgba(0,0,0,0.1)';
container.style.maxWidth = '100%';
container.style.boxSizing = 'border-box';
// Add title in English and Russian as per the quirky description
const title = document.createElement('h2');
title.style.margin = '0 0 5px 0';
title.style.textAlign = 'center';
title.style.color = '#333';
title.innerText = 'Color Scanner Identifier';
const subTitle = document.createElement('p');
subTitle.style.margin = '0 0 20px 0';
subTitle.style.color = '#777';
subTitle.style.fontSize = '14px';
subTitle.innerText = 'Обзор Шампунь русских цвет Сканер идентификатор';
container.appendChild(title);
container.appendChild(subTitle);
const canvasContainer = document.createElement('div');
canvasContainer.style.position = 'relative';
canvasContainer.style.maxWidth = '100%';
canvasContainer.style.overflow = 'hidden';
canvasContainer.style.borderRadius = '8px';
canvasContainer.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)';
canvasContainer.style.cursor = 'crosshair';
canvasContainer.style.touchAction = 'none'; // Prevents scrolling while scanning on touch devices
const canvas = document.createElement('canvas');
let ctx;
try {
ctx = canvas.getContext('2d', { willReadFrequently: true });
} catch(e) {
ctx = canvas.getContext('2d');
}
// Scale image if it's too large for visual display, keeping proportions
const maxDimension = 600;
let scale = 1;
if (originalImg.width > maxDimension || originalImg.height > maxDimension) {
scale = Math.min(maxDimension / originalImg.width, maxDimension / originalImg.height);
}
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Set the display size scaled down
canvas.style.width = (originalImg.width * scale) + 'px';
canvas.style.height = (originalImg.height * scale) + 'px';
canvas.style.display = 'block';
ctx.drawImage(originalImg, 0, 0);
canvasContainer.appendChild(canvas);
container.appendChild(canvasContainer);
const infoPanel = document.createElement('div');
infoPanel.style.display = 'flex';
infoPanel.style.gap = '20px';
infoPanel.style.marginTop = '20px';
infoPanel.style.width = '100%';
infoPanel.style.maxWidth = Math.max(600, originalImg.width * scale) + 'px';
infoPanel.style.justifyContent = 'space-between';
infoPanel.style.flexWrap = 'wrap';
const liveScanner = document.createElement('div');
liveScanner.style.flex = '1';
liveScanner.style.minWidth = '250px';
liveScanner.style.display = 'flex';
liveScanner.style.alignItems = 'center';
liveScanner.style.gap = '15px';
liveScanner.style.padding = '15px';
liveScanner.style.backgroundColor = '#fff';
liveScanner.style.border = '1px solid #e0e0e0';
liveScanner.style.borderRadius = '8px';
const colorDisplay = document.createElement('div');
colorDisplay.style.width = '64px';
colorDisplay.style.height = '64px';
colorDisplay.style.borderRadius = '50%';
colorDisplay.style.border = '2px solid #ddd';
colorDisplay.style.backgroundColor = 'transparent';
colorDisplay.style.boxShadow = 'inset 0 0 8px rgba(0,0,0,0.1)';
colorDisplay.style.flexShrink = '0';
const colorInfo = document.createElement('div');
colorInfo.style.lineHeight = '1.6';
colorInfo.style.fontSize = '14px';
colorInfo.innerHTML = '<strong style="color:#555;">Hover over the image</strong><br><span style="color:#888; font-size:12px;">(Наведите курсор на изображение)</span><br>HEX: -<br>RGB: -';
liveScanner.appendChild(colorDisplay);
liveScanner.appendChild(colorInfo);
const domColorsPanel = document.createElement('div');
domColorsPanel.style.flex = '1';
domColorsPanel.style.minWidth = '250px';
domColorsPanel.style.padding = '15px';
domColorsPanel.style.backgroundColor = '#fff';
domColorsPanel.style.border = '1px solid #e0e0e0';
domColorsPanel.style.borderRadius = '8px';
const domTitle = document.createElement('strong');
domTitle.innerHTML = 'Dominant Colors <br><span style="color:#888; font-weight:normal; font-size:12px;">(Доминирующие цвета)</span>';
domTitle.style.display = 'block';
domTitle.style.marginBottom = '12px';
domTitle.style.color = '#444';
domColorsPanel.appendChild(domTitle);
const palette = document.createElement('div');
palette.style.display = 'flex';
palette.style.gap = '10px';
palette.style.flexWrap = 'wrap';
domColorsPanel.appendChild(palette);
infoPanel.appendChild(liveScanner);
infoPanel.appendChild(domColorsPanel);
container.appendChild(infoPanel);
function rgbToHex(r, g, b) {
return "#" + (1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1).toUpperCase();
}
function handleMove(e) {
if (e.type === 'touchmove') e.preventDefault();
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
let clientX = e.clientX;
let clientY = e.clientY;
// Handle touch inputs
if (e.touches && e.touches.length > 0) {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
}
let x = (clientX - rect.left) * scaleX;
let y = (clientY - rect.top) * scaleY;
x = Math.max(0, Math.min(canvas.width - 1, Math.floor(x)));
y = Math.max(0, Math.min(canvas.height - 1, Math.floor(y)));
const pixel = ctx.getImageData(x, y, 1, 1).data;
const r = pixel[0];
const g = pixel[1];
const b = pixel[2];
const a = pixel[3];
if (a === 0) {
colorDisplay.style.backgroundColor = 'transparent';
colorInfo.innerHTML = '<strong style="color:#555;">Transparent Pixel</strong><br><span style="color:#888; font-size:12px;">(Прозрачный пиксель)</span><br>HEX: -<br>RGB: -';
return;
}
const hex = rgbToHex(r, g, b);
colorDisplay.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
colorInfo.innerHTML = `<strong style="color:#222;">Scanned Color</strong> <span style="color:#888; font-size:12px;">(Сканированный цвет)</span><br><span style="font-family:monospace; font-size:14px; color:#c0392b;"><b>HEX: ${hex}</b><br><b>RGB: ${r}, ${g}, ${b}</b></span>`;
}
canvas.addEventListener('mousemove', handleMove);
canvas.addEventListener('touchmove', handleMove, { passive: false });
function handleLeave() {
colorDisplay.style.backgroundColor = 'transparent';
colorInfo.innerHTML = '<strong style="color:#555;">Hover over the image</strong><br><span style="color:#888; font-size:12px;">(Наведите курсор на изображение)</span><br>HEX: -<br>RGB: -';
}
canvas.addEventListener('mouseleave', handleLeave);
canvas.addEventListener('touchend', handleLeave);
// Compute dominant colors asynchronously to not block the main render
setTimeout(() => {
const smallCanvas = document.createElement('canvas');
smallCanvas.width = 100;
const aspect = canvas.width > 0 ? (canvas.height / canvas.width) : 1;
smallCanvas.height = Math.max(1, Math.floor(100 * aspect));
const smallCtx = smallCanvas.getContext('2d');
smallCtx.drawImage(originalImg, 0, 0, smallCanvas.width, smallCanvas.height);
const imageData = smallCtx.getImageData(0, 0, smallCanvas.width, smallCanvas.height).data;
const colorMap = {};
// Simple color quantization and frequency counting
for (let i = 0; i < imageData.length; i += 4) {
if (imageData[i+3] > 128) {
const r = Math.floor(imageData[i] / 32) * 32 + 16;
const g = Math.floor(imageData[i+1] / 32) * 32 + 16;
const b = Math.floor(imageData[i+2] / 32) * 32 + 16;
const rgb = `${r},${g},${b}`;
colorMap[rgb] = (colorMap[rgb] || 0) + 1;
}
}
const sorted = Object.entries(colorMap).sort((a, b) => b[1] - a[1]);
const dominant = sorted.slice(0, count).map(v => {
const parts = v[0].split(',');
return {
r: parseInt(parts[0], 10),
g: parseInt(parts[1], 10),
b: parseInt(parts[2], 10)
};
});
if (dominant.length === 0) {
palette.innerText = "No colors found. (Цвета не найдены.)";
} else {
dominant.forEach(col => {
const hex = rgbToHex(col.r, col.g, col.b);
const swatchContainer = document.createElement('div');
swatchContainer.style.display = 'flex';
swatchContainer.style.flexDirection = 'column';
swatchContainer.style.alignItems = 'center';
swatchContainer.style.gap = '5px';
swatchContainer.style.cursor = 'pointer';
const swatch = document.createElement('div');
swatch.style.width = '36px';
swatch.style.height = '36px';
swatch.style.backgroundColor = hex;
swatch.style.borderRadius = '6px';
swatch.style.border = '1px solid #ccc';
swatch.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
swatch.title = "Click to copy / Нажмите, чтобы скопировать";
const label = document.createElement('span');
label.innerText = hex;
label.style.fontSize = '12px';
label.style.fontFamily = 'monospace';
label.style.color = '#555';
swatchContainer.appendChild(swatch);
swatchContainer.appendChild(label);
// Add click-to-copy hex functionality
swatchContainer.addEventListener('click', () => {
navigator.clipboard.writeText(hex).then(() => {
const originalText = label.innerText;
label.innerText = 'Copied!';
label.style.color = 'green';
setTimeout(() => {
label.innerText = originalText;
label.style.color = '#555';
}, 1000);
}).catch(() => {
label.innerText = 'Failed';
label.style.color = 'red';
});
});
palette.appendChild(swatchContainer);
});
}
}, 50);
return container;
}
Apply Changes