Please bookmark this page to avoid losing your image tool!

Russian Shampoo Color Scanner Identifier Tool

(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, 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;
}

Free Image Tool Creator

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

Description

This tool allows users to identify and extract specific color information from any uploaded image. It features an interactive color scanner where you can hover your cursor over any part of an image to instantly retrieve its HEX and RGB values. Additionally, the tool automatically analyzes the image to generate a palette of its most dominant colors, providing the HEX codes for easy copying. This utility is useful for graphic designers, web developers, and artists looking to replicate color schemes from photos or digital artwork.

Leave a Reply

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