Please bookmark this page to avoid losing your image tool!

Image Comparison Tool For Logo And Music Analysis

(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.
/**
 * Helper function to convert an RGB color value to HSL. This is used to determine the "mood" from the logo's average color.
 * @param {number} r The red color value [0, 255]
 * @param {number} g The green color value [0, 255]
 * @param {number} b The blue color value [0, 255]
 * @returns {Array<number>} An array containing the HSL values [hue, saturation, lightness].
 */
function rgbToHsl(r, g, b) {
    r /= 255, g /= 255, b /= 255;
    let max = Math.max(r, g, b), min = Math.min(r, g, b);
    let h = 0, s = 0, l = (max + min) / 2;

    if (max !== min) {
        let d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }
    return [h * 360, s * 100, l * 100];
}

/**
 * Creates a visual comparison between a logo and a "musical interpretation" based on the logo's visual properties.
 * @param {Image} originalImg The input Image object (the logo).
 * @param {string} backgroundColor The background color of the output canvas.
 * @param {string} textColor The color for text and borders on the canvas.
 * @returns {HTMLCanvasElement} A canvas element containing the side-by-side comparison and analysis.
 */
function processImage(originalImg, backgroundColor = '#1a1a1a', textColor = '#ffffff') {
    // 1. Setup Canvas
    const padding = 40;
    const spacing = 40;
    const textHeight = 120;

    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width * 2 + padding * 2 + spacing;
    canvas.height = originalImg.height + padding * 2 + textHeight;
    const ctx = canvas.getContext('2d');

    // Fill background
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 2. Analyze Image to get average color and brightness
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = originalImg.width;
    tempCanvas.height = originalImg.height;
    // Use willReadFrequently hint for potential performance improvement
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
    tempCtx.drawImage(originalImg, 0, 0);

    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, originalImg.width, originalImg.height);
    } catch (e) {
        // Handle potential security errors (tainted canvas) if the image is from a different origin
        ctx.fillStyle = textColor;
        ctx.textAlign = 'center';
        ctx.font = '16px Arial, sans-serif';
        ctx.fillText('Could not process image due to cross-origin restrictions.', canvas.width / 2, canvas.height / 2);
        console.error("Canvas Tainted:", e);
        return canvas;
    }

    const data = imageData.data;
    let totalR = 0, totalG = 0, totalB = 0, totalBrightness = 0;
    const pixelCount = originalImg.width * originalImg.height;

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        totalR += r;
        totalG += g;
        totalB += b;
        totalBrightness += (r + g + b) / 3;
    }

    const avgR = Math.round(totalR / pixelCount);
    const avgG = Math.round(totalG / pixelCount);
    const avgB = Math.round(totalB / pixelCount);
    const avgBrightness = Math.round(totalBrightness / pixelCount);
    const avgColorHex = `#${avgR.toString(16).padStart(2, '0')}${avgG.toString(16).padStart(2, '0')}${avgB.toString(16).padStart(2, '0')}`;

    // 3. Draw Logo
    const logoX = padding;
    const logoY = padding;
    ctx.drawImage(originalImg, logoX, logoY, originalImg.width, originalImg.height);

    ctx.strokeStyle = textColor;
    ctx.lineWidth = 1;
    ctx.strokeRect(logoX - 1, logoY - 1, originalImg.width + 2, originalImg.height + 2);

    // 4. Generate and Draw "Music" Visualization
    const vizX = logoX + originalImg.width + spacing;
    const vizY = logoY;
    const vizWidth = originalImg.width;
    const vizHeight = originalImg.height;

    ctx.strokeRect(vizX - 1, vizY - 1, vizWidth + 2, vizHeight + 2);

    ctx.save();
    ctx.beginPath();
    ctx.rect(vizX, vizY, vizWidth, vizHeight);
    ctx.clip(); // Clip drawing to the visualization box

    const centerY = vizY + vizHeight / 2;
    const amplitude = (avgBrightness / 255) * (vizHeight * 0.4);

    // Use average colors to create a unique and complex waveform
    const freqR = (avgR / 255) * 4 + 1;
    const freqG = (avgG / 255) * 4 + 2;
    const freqB = (avgB / 255) * 4 + 3;
    const pseudoRandom = (avgR + avgG + avgB) % 17 / 17;

    ctx.lineWidth = 2;
    ctx.strokeStyle = avgColorHex;

    ctx.beginPath();
    ctx.moveTo(vizX, centerY);

    for (let x = 0; x < vizWidth; x++) {
        const angle = (x / vizWidth) * Math.PI * 6; // Three full waves
        const yOffset =
            (Math.sin(angle * freqR + pseudoRandom) * (avgR / 255) +
             Math.cos(angle * freqG + pseudoRandom) * (avgG / 255) +
             Math.sin(angle * freqB + pseudoRandom) * (avgB / 255)) / 3;

        const y = centerY + yOffset * amplitude;
        ctx.lineTo(vizX + x, y);
    }
    ctx.stroke();
    ctx.restore();

    // 5. Draw Text Analysis
    ctx.fillStyle = textColor;
    ctx.font = 'bold 16px "Segoe UI", Arial, sans-serif';
    ctx.textAlign = 'center';

    const textRegionY = logoY + originalImg.height + 40;
    const logoTextX = logoX + originalImg.width / 2;
    const musicTextX = vizX + vizWidth / 2;

    ctx.fillText('Logo Analysis', logoTextX, textRegionY);
    ctx.fillText('Music Interpretation', musicTextX, textRegionY);

    ctx.font = '14px "Segoe UI", Arial, sans-serif';
    const line1Y = textRegionY + 30;
    const line2Y = textRegionY + 55;
    const line3Y = textRegionY + 80;

    // Logo Analysis Details
    ctx.textAlign = 'left';
    ctx.fillText('Avg. Color:', logoX, line1Y);
    ctx.fillStyle = avgColorHex;
    ctx.fillRect(logoX + 90, line1Y - 12, 50, 16);
    ctx.fillStyle = textColor;
    ctx.fillText(avgColorHex.toUpperCase(), logoX + 150, line1Y);
    ctx.fillText(`Brightness: ${Math.round(avgBrightness / 255 * 100)}%`, logoX, line2Y);

    // Music Interpretation Details
    const [hue] = rgbToHsl(avgR, avgG, avgB);
    let mood = "Balanced";
    if (hue >= 0 && hue < 30) mood = "Passionate"; else if (hue < 60) mood = "Joyful";
    else if (hue < 90) mood = "Fresh"; else if (hue < 150) mood = "Natural";
    else if (hue < 210) mood = "Serene"; else if (hue < 270) mood = "Calm";
    else if (hue < 330) mood = "Royal"; else mood = "Passionate";

    let tempo = "Andante (moderate)";
    if (avgBrightness < 85) tempo = "Largo (slow)";
    if (avgBrightness > 170) tempo = "Presto (fast)";

    const colorRange = Math.max(avgR, avgG, avgB) - Math.min(avgR, avgG, avgB);
    let texture = "Monophonic";
    if (colorRange > 50) texture = "Polyphonic";
    if (colorRange > 120) texture = "Harmonically Rich";

    ctx.fillText(`Mood: ${mood}`, vizX, line1Y);
    ctx.fillText(`Tempo: ${tempo}`, vizX, line2Y);
    ctx.fillText(`Texture: ${texture}`, vizX, line3Y);

    return canvas;
}

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 Comparison Tool for Logo and Music Analysis allows users to visually compare a logo with a musical interpretation inspired by the logo’s visual properties. By analyzing the average color and brightness of the logo, the tool generates a side-by-side canvas that displays the logo alongside a unique visualization that reflects its visual attributes through sound metaphors. This tool can be particularly useful for brand designers and marketers seeking to understand the emotional impact of a logo or for artists looking to explore the intersection of visual art and music. It provides insights into the logo’s average color, perceived mood, tempo, and texture, helping inform design choices and creative directions.

Leave a Reply

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