Please bookmark this page to avoid losing your image tool!

Audio To Image Fanfare Generator

(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, titleText = "UNIVERSAL", subtitleText = "AUDIO TO IMAGE FANFARE", textColor = "#FFD700") {
    // Create the main container
    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.width = '100%';
    container.style.maxWidth = '800px';
    container.style.margin = '0 auto';
    container.style.fontFamily = 'Arial, sans-serif';
    container.style.overflow = 'hidden';
    container.style.backgroundColor = '#000';
    container.style.border = '2px solid #333';
    container.style.borderRadius = '8px';
    container.style.boxShadow = '0 10px 30px rgba(0,0,0,0.8)';

    // Create Canvas
    const canvas = document.createElement('canvas');
    canvas.width = 800;
    canvas.height = 450; // 16:9 Aspect Ratio
    canvas.style.width = '100%';
    canvas.style.display = 'block';
    container.appendChild(canvas);

    const ctx = canvas.getContext('2d');

    // Create the "Play Fanfare" overlay button
    const btn = document.createElement('button');
    btn.innerHTML = '🎬 Generate & Play Fanfare';
    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 = '20px';
    btn.style.fontWeight = 'bold';
    btn.style.cursor = 'pointer';
    btn.style.color = '#333';
    btn.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
    btn.style.border = '2px solid #FFF';
    btn.style.borderRadius = '30px';
    btn.style.boxShadow = '0 0 20px rgba(0,0,0,0.8)';
    btn.style.transition = 'all 0.3s ease';
    btn.style.zIndex = 10;
    
    btn.onmouseover = () => {
        btn.style.backgroundColor = '#FFF';
        btn.style.transform = 'translate(-50%, -50%) scale(1.05)';
    };
    btn.onmouseout = () => {
        btn.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
        btn.style.transform = 'translate(-50%, -50%) scale(1)';
    };
    container.appendChild(btn);

    // Pre-generate stars for the space background
    const stars = [];
    for (let i = 0; i < 250; i++) {
        stars.push({
            x: Math.random() * canvas.width,
            y: Math.random() * canvas.height,
            r: Math.random() * 1.5,
            a: Math.random() * Math.PI * 2
        });
    }

    let animating = false;
    let startTime = 0;
    let animationId = null;

    // Helper to draw the frame based on elapsed time
    function drawFrame(time) {
        if (!startTime) startTime = time;
        const elapsed = (time - startTime) / 1000; // in seconds

        const cx = canvas.width / 2;
        const cy = canvas.height / 2;
        const globeRadius = 160;

        // 1. Draw Space Background
        ctx.fillStyle = '#01010a';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        stars.forEach(s => {
            const opacity = (Math.sin(elapsed * 2 + s.a) + 1) / 2;
            ctx.fillStyle = `rgba(255, 255, 255, ${opacity * 0.8})`;
            ctx.beginPath();
            ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
            ctx.fill();
        });

        // 2. Cinematic Sunburst / Light Rays behind the globe
        const rayAlpha = Math.min(1, Math.max(0, elapsed - 0.5) / 2);
        if (rayAlpha > 0) {
            ctx.save();
            ctx.translate(cx, cy);
            ctx.rotate(elapsed * 0.05); // Slow rotation of rays
            const numRays = 40;
            const rayLen = 500;
            
            for (let i = 0; i < numRays; i++) {
                const rot = (i / numRays) * Math.PI * 2;
                ctx.rotate(rot);
                const rayGrad = ctx.createLinearGradient(globeRadius - 20, 0, rayLen, 0);
                rayGrad.addColorStop(0, `rgba(255, 230, 150, ${0.4 * rayAlpha})`);
                rayGrad.addColorStop(1, 'rgba(255, 230, 150, 0)');
                
                ctx.fillStyle = rayGrad;
                ctx.beginPath();
                ctx.moveTo(globeRadius - 20, -10);
                ctx.lineTo(rayLen, -30);
                ctx.lineTo(rayLen, 30);
                ctx.lineTo(globeRadius - 20, 10);
                ctx.fill();
                ctx.rotate(-rot);
            }
            ctx.restore();
        }

        // 3. Draw Rotating Globe (using originalImg)
        ctx.save();
        ctx.beginPath();
        ctx.arc(cx, cy, globeRadius, 0, Math.PI * 2);
        ctx.clip();

        const imgAspect = originalImg.width / originalImg.height;
        const drawH = globeRadius * 2;
        const drawW = drawH * imgAspect;
        const speed = 40; // Spinning speed (pixels per second)
        const panX = (elapsed * speed) % drawW;

        // Tile the image to make it seamlessly loop
        const numTiles = Math.ceil((globeRadius * 2) / drawW) + 1;
        for (let i = -1; i < numTiles; i++) {
            ctx.drawImage(originalImg, cx - globeRadius - panX + (i * drawW), cy - globeRadius, drawW, drawH);
        }

        // Apply spherical shadow for 3D effect
        const sphereGrad = ctx.createRadialGradient(cx - globeRadius/2.5, cy - globeRadius/2.5, globeRadius/5, cx, cy, globeRadius);
        sphereGrad.addColorStop(0, 'rgba(255,255,255,0.3)');
        sphereGrad.addColorStop(0.6, 'rgba(0,0,0,0.2)');
        sphereGrad.addColorStop(0.95, 'rgba(0,0,0,0.85)');
        sphereGrad.addColorStop(1, 'rgba(0,0,0,1)');
        
        ctx.fillStyle = sphereGrad;
        ctx.fillRect(cx - globeRadius, cy - globeRadius, globeRadius * 2, globeRadius * 2);
        ctx.restore();

        // Outer glow
        const glowAlpha = Math.min(0.6, elapsed / 3);
        const outerGlow = ctx.createRadialGradient(cx, cy, globeRadius, cx, cy, globeRadius + 30);
        outerGlow.addColorStop(0, `rgba(100, 200, 255, ${glowAlpha})`);
        outerGlow.addColorStop(1, 'rgba(100, 200, 255, 0)');
        ctx.fillStyle = outerGlow;
        ctx.beginPath();
        ctx.arc(cx, cy, globeRadius + 30, 0, Math.PI * 2);
        ctx.fill();

        // 4. Draw Cinematic Arching Text
        // Timing syncs with music hit at 3.4 seconds
        const introPhase = Math.min(1, Math.max(0, elapsed - 0.5) / 2.9);
        if (introPhase > 0) {
            // Cubic ease-out calculation for smooth settling
            const easeOut = 1 - Math.pow(1 - introPhase, 3);
            const scale = 0.5 + (easeOut * 0.5);
            const ringRotation = (1 - easeOut) * (Math.PI / 2.5); // Sweeps in from an angle

            ctx.font = 'bold 55px "Trebuchet MS", Helvetica, sans-serif';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';

            const chars = titleText.split('');
            const totalSweep = Math.PI * 0.75; 

            chars.forEach((c, idx) => {
                const charProgress = idx / (chars.length - 1 || 1);
                const angle = -totalSweep/2 + totalSweep * charProgress;
                
                ctx.save();
                ctx.translate(cx, cy);
                
                // Add gentle scale and perspective tilt
                ctx.scale(scale, scale);
                // Orbit math around the globe (elliptical)
                const orbitX = Math.sin(angle - ringRotation) * (globeRadius + 45);
                const orbitY = Math.cos(angle - ringRotation) * 45;
                
                ctx.translate(orbitX, orbitY);
                // Rotate letter slightly to follow the curve
                ctx.rotate((angle - ringRotation) * 0.35);

                // Golden text gradient
                const textGrad = ctx.createLinearGradient(0, -30, 0, 30);
                textGrad.addColorStop(0, textColor);
                textGrad.addColorStop(0.4, '#FFFFE0');
                textGrad.addColorStop(0.6, '#DAA520');
                textGrad.addColorStop(1, '#8B6508');

                ctx.fillStyle = textGrad;
                
                // Solid shadow
                ctx.shadowColor = 'rgba(0,0,0,0.9)';
                ctx.shadowBlur = 8;
                ctx.shadowOffsetX = 3;
                ctx.shadowOffsetY = 4;
                
                ctx.fillText(c, 0, 0);

                // Thin stroke to define edges
                ctx.shadowColor = 'transparent';
                ctx.strokeStyle = '#222';
                ctx.lineWidth = 1.0;
                ctx.strokeText(c, 0, 0);

                ctx.restore();
            });
        }

        // 5. Fade in Subtitle Text
        if (elapsed > 4.0) {
            const subAlpha = Math.min(1, (elapsed - 4.0) / 1.5);
            ctx.fillStyle = `rgba(255, 255, 255, ${subAlpha * 0.8})`;
            ctx.font = '14px Arial, sans-serif';
            ctx.textAlign = 'center';
            ctx.letterSpacing = '5px'; // HTML5 canvas hack for letter spacing requires modern canvas or spaces
            const spacedSub = subtitleText.split('').join(String.fromCharCode(8202));
            ctx.fillText(spacedSub, cx, cy + globeRadius + 60);
        }

        // 6. Global Fade from Black at start
        if (elapsed < 1.0) {
            ctx.fillStyle = `rgba(0,0,0,${1 - (elapsed / 1.0)})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        if (animating && elapsed < 12.0) {
            animationId = requestAnimationFrame(drawFrame);
        } else if (animating) {
            animating = false;
        }
    }

    // Synthesize the classic "David Newman-esc" Orchestral Fanfare
    function startAudioFanfare() {
        const AudioContext = window.AudioContext || window.webkitAudioContext;
        if (!AudioContext) return;
        const audioCtx = new AudioContext();
        
        const masterGain = audioCtx.createGain();
        masterGain.gain.value = 0.6; // Base volume
        masterGain.connect(audioCtx.destination);

        // Helper func to play synthesized brass instruments
        function playBrassWave(freq, type, tStart, tDur) {
            const osc = audioCtx.createOscillator();
            osc.type = type;
            osc.frequency.setValueAtTime(freq, audioCtx.currentTime + tStart);
            
            const filter = audioCtx.createBiquadFilter();
            filter.type = 'lowpass';
            // Classic swelling brass filter envelope
            filter.frequency.setValueAtTime(300, audioCtx.currentTime + tStart);
            filter.frequency.linearRampToValueAtTime(3500, audioCtx.currentTime + tStart + Math.min(tDur*0.4, 0.5));
            filter.frequency.exponentialRampToValueAtTime(500, audioCtx.currentTime + tStart + tDur);
            
            const gain = audioCtx.createGain();
            gain.gain.setValueAtTime(0, audioCtx.currentTime + tStart);
            gain.gain.linearRampToValueAtTime(1, audioCtx.currentTime + tStart + 0.05);
            gain.gain.setValueAtTime(1, audioCtx.currentTime + tStart + tDur - 0.2);
            gain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + tStart + tDur);
            
            osc.connect(filter);
            filter.connect(gain);
            gain.connect(masterGain);
            
            osc.start(audioCtx.currentTime + tStart);
            osc.stop(audioCtx.currentTime + tStart + tDur + 0.1);
        }

        // Generate synthetic drum hit (tympani & crash)
        function playDrumHit(tStart) {
            // Tympani (low boom)
            const osc = audioCtx.createOscillator();
            const gain = audioCtx.createGain();
            osc.type = 'sine';
            osc.frequency.setValueAtTime(120, audioCtx.currentTime + tStart);
            osc.frequency.exponentialRampToValueAtTime(40, audioCtx.currentTime + tStart + 0.4);
            gain.gain.setValueAtTime(1.5, audioCtx.currentTime + tStart);
            gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + tStart + 2.0);
            osc.connect(gain);
            gain.connect(masterGain);
            osc.start(audioCtx.currentTime + tStart);
            osc.stop(audioCtx.currentTime + tStart + 2.1);

            // Crash noise generator
            const bufferSize = audioCtx.sampleRate * 1.0;
            const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
            const data = buffer.getChannelData(0);
            for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;
            
            const noise = audioCtx.createBufferSource();
            noise.buffer = buffer;
            const noiseFilter = audioCtx.createBiquadFilter();
            noiseFilter.type = 'highpass';
            noiseFilter.frequency.value = 1000;
            
            const nGain = audioCtx.createGain();
            nGain.gain.setValueAtTime(0.7, audioCtx.currentTime + tStart);
            nGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + tStart + 1.0);
            
            noise.connect(noiseFilter);
            noiseFilter.connect(nGain);
            nGain.connect(masterGain);
            noise.start(audioCtx.currentTime + tStart);
            noise.stop(audioCtx.currentTime + tStart + 1.2);
        }

        // Newman fanfare approximate note sheet
        const fanfareNotes = [
            // Opening Stabs
            {f: 196.00, t: 0.5, d: 0.8}, // G3
            {f: 196.00, t: 1.5, d: 0.8}, // G3
            // Running triplet buildup
            {f: 196.00, t: 2.5, d: 0.3}, // G3
            {f: 220.00, t: 2.8, d: 0.3}, // A3
            {f: 246.94, t: 3.1, d: 0.3}, // B3
            // Epic chord land (Synced visually to 3.4s)
            {f: 261.63, t: 3.4, d: 2.0}, // C4
            {f: 130.81, t: 3.4, d: 2.0}, // C3 harmony
            {f: 164.81, t: 3.4, d: 2.0}, // E3 harmony
            // The melody rise
            {f: 196.00, t: 5.6, d: 0.4}, // G3
            {f: 261.63, t: 6.0, d: 0.4}, // C4
            {f: 329.63, t: 6.4, d: 0.4}, // E4
            // Final resolved crescendo
            {f: 392.00, t: 6.8, d: 4.5}, // G4
            {f: 261.63, t: 6.8, d: 4.5}, // C4 
            {f: 523.25, t: 6.8, d: 4.5}, // C5
            {f: 130.81, t: 6.8, d: 4.5}  // C3 (Bass)
        ];

        // Synthesize full chord for each note mapping
        fanfareNotes.forEach(n => {
            playBrassWave(n.f, 'sawtooth', n.t, n.d);
            playBrassWave(n.f * 1.005, 'sawtooth', n.t, n.d); // slight detune for chorusing
            playBrassWave(n.f * 0.5, 'square', n.t, n.d);    // sub octave fatness
        });

        // Add cinematic drums mapped to the main beats
        playDrumHit(0.5);
        playDrumHit(1.5);
        playDrumHit(3.4); // Syncs precisely to text scaling finish
        playDrumHit(6.8); // Final major swelling hit

        // Background Snare Roll building up to t=3.4
        const rollDuration = 2.9;
        const sBuffer = audioCtx.createBuffer(1, audioCtx.sampleRate * rollDuration, audioCtx.sampleRate);
        const sData = sBuffer.getChannelData(0);
        for(let i=0; i < sBuffer.length; i++) sData[i] = (Math.random()*2 - 1) * 0.5;
        const snareSrc = audioCtx.createBufferSource();
        snareSrc.buffer = sBuffer;
        
        const snareFilter = audioCtx.createBiquadFilter();
        snareFilter.type = 'bandpass';
        snareFilter.frequency.value = 1200;
        
        const snareGain = audioCtx.createGain();
        snareGain.gain.setValueAtTime(0, audioCtx.currentTime + 0.5);
        snareGain.gain.exponentialRampToValueAtTime(0.8, audioCtx.currentTime + 3.3);
        snareGain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 3.4);
        
        snareSrc.connect(snareFilter);
        snareFilter.connect(snareGain);
        snareGain.connect(masterGain);
        snareSrc.start(audioCtx.currentTime + 0.5);
        snareSrc.stop(audioCtx.currentTime + 3.4);
        
        if (audioCtx.state === 'suspended') {
            audioCtx.resume();
        }
    }

    // Launch mechanism
    btn.addEventListener('click', () => {
        btn.style.display = 'none';
        
        if (animationId) cancelAnimationFrame(animationId);
        
        // Kick off Drawing & Synth Track concurrently!
        animating = true;
        startTime = 0;
        requestAnimationFrame(drawFrame);
        startAudioFanfare();
    });

    // Draw initial static frame (Pitch Black)
    ctx.fillStyle = '#000000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    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

The Audio to Image Fanfare Generator is a creative tool that transforms a static image into a cinematic, animated sequence accompanied by a synthesized orchestral fanfare. When activated, the tool applies a 3D spherical effect to your uploaded image, making it appear as a rotating globe set against a starry space background with sunburst light rays. It also features dynamic, arching golden text overlays and subtitles that synchronize with a custom-generated brass and percussion soundtrack. This tool is ideal for creating dramatic intros, celebratory announcements, or high-impact visual transitions for presentations and social media content.

Leave a Reply

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