Please bookmark this page to avoid losing your image tool!

AI Powered Music Creator 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, bpm = 120, mood = "Happy") {
    // Create container
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'inline-block';
    container.style.fontFamily = 'Arial, sans-serif';
    container.style.boxShadow = '0 10px 30px rgba(0,0,0,0.5)';
    container.style.borderRadius = '8px';
    container.style.overflow = 'hidden';

    // Main visualizer canvas
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);
    container.appendChild(canvas);

    // Overlay controls
    const btn = document.createElement('button');
    btn.innerText = '▶ Generate & Play AI Music';
    btn.style.position = 'absolute';
    btn.style.top = '50%';
    btn.style.left = '50%';
    btn.style.transform = 'translate(-50%, -50%)';
    btn.style.padding = '15px 30px';
    btn.style.fontSize = '18px';
    btn.style.fontWeight = 'bold';
    btn.style.cursor = 'pointer';
    btn.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
    btn.style.color = '#333';
    btn.style.border = 'none';
    btn.style.borderRadius = '50px';
    btn.style.boxShadow = '0 4px 15px rgba(0,0,0,0.3)';
    btn.style.transition = 'all 0.3s ease';
    btn.style.zIndex = '10';

    btn.onmouseover = () => {
        btn.style.transform = 'translate(-50%, -50%) scale(1.05)';
        btn.style.backgroundColor = '#fff';
    };
    btn.onmouseout = () => {
        btn.style.transform = 'translate(-50%, -50%) scale(1)';
        btn.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
    };
    container.appendChild(btn);

    // Music generation variables
    let audioCtx = null;
    let isPlaying = false;
    let intervalId = null;
    const gridSize = 16; 

    // Helper to generate scale frequencies based on mood
    function getScaleFrequencies(selectedMood) {
        const baseFreq = 130.81; // C3
        const f = (steps) => baseFreq * Math.pow(2, steps / 12);
        
        let intervals;
        if (selectedMood.toLowerCase() === 'sad') {
            intervals = [0, 3, 5, 7, 10]; // C Minor Pentatonic
        } else if (selectedMood.toLowerCase() === 'mysterious') {
            intervals = [0, 2, 4, 6, 8, 10]; // Whole tone
        } else {
            intervals = [0, 2, 4, 7, 9]; // C Major Pentatonic (Happy)
        }

        const freqs = [];
        for (let octave = 0; octave < 4; octave++) {
            for (let i = 0; i < intervals.length; i++) {
                freqs.push(f(intervals[i] + octave * 12));
                if (freqs.length === gridSize) break;
            }
            if (freqs.length === gridSize) break;
        }
        return freqs.reverse(); // high frequencies at the top (low Y index)
    }

    btn.addEventListener('click', () => {
        if (isPlaying) {
            // Stop logic
            clearInterval(intervalId);
            if (audioCtx) {
                audioCtx.close();
                audioCtx = null;
            }
            isPlaying = false;
            btn.innerText = '▶ Play AI Music';
            ctx.drawImage(originalImg, 0, 0); // reset visualizer
            return;
        }

        // Start logic
        isPlaying = true;
        btn.innerText = '■ Stop Music';
        
        // Initialize Web Audio API
        const AudioContext = window.AudioContext || window.webkitAudioContext;
        audioCtx = new AudioContext();

        // 1. Image Analysis (The "AI" processing)
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = gridSize;
        tempCanvas.height = gridSize;
        const tCtx = tempCanvas.getContext('2d');
        tCtx.drawImage(originalImg, 0, 0, gridSize, gridSize);
        const imgData = tCtx.getImageData(0, 0, gridSize, gridSize).data;

        const scale = getScaleFrequencies(mood);
        const melody = [];

        // Map columns to time, rows to pitch
        for (let x = 0; x < gridSize; x++) {
            let notes = [];
            for (let y = 0; y < gridSize; y++) {
                const i = (y * gridSize + x) * 4;
                const r = imgData[i];
                const g = imgData[i+1];
                const b = imgData[i+2];
                const brightness = (r + g + b) / 3;

                // Threshold to trigger notes, preserving polyphony
                if (brightness > 100) { 
                    // Select instrument based on dominant hue
                    let type = 'sine';
                    if (r > g + 20 && r > b + 20) type = 'sawtooth';
                    else if (g > r + 20 && g > b + 20) type = 'triangle';
                    else if (b > r + 20 && b > g + 20) type = 'square';

                    // Volume tied to brightness pixel value
                    const volume = (brightness / 255) * 0.15; 
                    notes.push({ freq: scale[y], type, vol: volume, y });
                }
            }

            // Fallback if the column is entirely dark (pick the brightest pixel)
            if (notes.length === 0) {
                let maxB = 0;
                let bestY = 0;
                for (let y = 0; y < gridSize; y++) {
                    const i = (y * gridSize + x) * 4;
                    const b = (imgData[i] + imgData[i+1] + imgData[i+2]) / 3;
                    if (b > maxB) { maxB = b; bestY = y; }
                }
                const vol = (maxB / 255) * 0.15;
                if(vol > 0.02) {
                    notes.push({ freq: scale[bestY], type: 'sine', vol, y: bestY });
                }
            }
            melody.push(notes);
        }

        // 2. Playback / Sequencer Loop
        const parsedBpm = Number(bpm) || 120;
        const stepTimeMs = 60000 / parsedBpm / 4; // 16th notes
        let currentStep = 0;
        
        ctx.lineWidth = 2;

        intervalId = setInterval(() => {
            const notes = melody[currentStep];

            // Render visualizer
            ctx.drawImage(originalImg, 0, 0);
            
            // Draw scanning playhead
            const colWidth = canvas.width / gridSize;
            
            ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
            ctx.fillRect(currentStep * colWidth, 0, colWidth, canvas.height);
            
            ctx.strokeStyle = '#fff';
            ctx.beginPath();
            ctx.moveTo(currentStep * colWidth + colWidth/2, 0);
            ctx.lineTo(currentStep * colWidth + colWidth/2, canvas.height);
            ctx.stroke();

            // Play notes and draw circles playing
            notes.forEach(note => {
                const osc = audioCtx.createOscillator();
                const gainNode = audioCtx.createGain();
                
                osc.type = note.type;
                osc.frequency.setValueAtTime(note.freq, audioCtx.currentTime);
                
                // Envelope
                gainNode.gain.setValueAtTime(0.001, audioCtx.currentTime);
                gainNode.gain.exponentialRampToValueAtTime(note.vol, audioCtx.currentTime + 0.05);
                gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + (stepTimeMs/1000) * 0.9);

                osc.connect(gainNode);
                gainNode.connect(audioCtx.destination);

                osc.start();
                osc.stop(audioCtx.currentTime + (stepTimeMs/1000));

                // Visual indicator for note hit
                ctx.beginPath();
                ctx.arc(
                    currentStep * colWidth + colWidth/2, 
                    note.y * (canvas.height / gridSize) + (canvas.height / gridSize)/2, 
                    Math.max(4, note.vol * 100), 
                    0, 2 * Math.PI
                );
                ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
                ctx.fill();
            });

            currentStep = (currentStep + 1) % gridSize;
        }, stepTimeMs);
    });

    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 AI-powered tool transforms static images into unique musical compositions by analyzing visual data. By processing an image’s color, brightness, and hue, the tool generates a melody and rhythm that reflects the visual elements. Users can customize the musical output by adjusting the tempo (BPM) and selecting a specific mood, such as happy, sad, or mysterious, which influences the musical scale used. This tool is ideal for content creators looking to generate synchronized soundtracks for visual art, musicians seeking inspiration from imagery, or anyone wanting to experience an interactive, multisensory interpretation of their photos.

Leave a Reply

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