Please bookmark this page to avoid losing your image tool!

Audio To Image Converter

(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.
async function processImage(originalImg, audioUrl = "", title = "Mp3 Audio HIFI", artist = "Audio To Image Converter", themeColor = "#1db954") {
    const width = 800;
    const height = 1200;
    
    // Create output canvas
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Helper for perfectly rounded rectangles 
    function drawRoundRect(ctx, x, y, width, height, radius) {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
        ctx.lineTo(x + radius, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
        ctx.lineTo(x, y + radius);
        ctx.quadraticCurveTo(x, y, x + radius, y);
        ctx.closePath();
    }

    // 1. Draw Player Background (Blurred original cover + dark gradient overlay)
    const bgScale = Math.max(width / originalImg.width, height / originalImg.height);
    const bgSw = width / bgScale;
    const bgSh = height / bgScale;
    const bgSx = (originalImg.width - bgSw) / 2;
    const bgSy = (originalImg.height - bgSh) / 2;

    if (typeof ctx.filter !== 'undefined') {
        ctx.save();
        ctx.filter = 'blur(60px) brightness(0.4)';
        // Draw slightly larger to avoid un-blurred edges
        ctx.drawImage(originalImg, bgSx, bgSy, bgSw, bgSh, -50, -50, width + 100, height + 100);
        ctx.restore();
    } else {
        // Fallback for setups without CSS filter support
        const bgGradient = ctx.createLinearGradient(0, 0, 0, height);
        bgGradient.addColorStop(0, '#1a1a2e');
        bgGradient.addColorStop(1, '#08080f');
        ctx.fillStyle = bgGradient;
        ctx.fillRect(0, 0, width, height);
    }

    // Overlay to ensure contrast
    const overlayGradient = ctx.createLinearGradient(0, 0, 0, height);
    overlayGradient.addColorStop(0, 'rgba(0, 0, 0, 0.4)');
    overlayGradient.addColorStop(1, 'rgba(15, 15, 20, 0.9)');
    ctx.fillStyle = overlayGradient;
    ctx.fillRect(0, 0, width, height);

    // 2. Draw Top HIFI Tag
    const badgeW = 200;
    const badgeH = 46;
    const badgeX = (width - badgeW) / 2;
    const badgeY = 50;

    ctx.strokeStyle = '#ffd700'; // Hi-Res gold 
    ctx.lineWidth = 2;
    drawRoundRect(ctx, badgeX, badgeY, badgeW, badgeH, 23);
    ctx.stroke();

    ctx.fillStyle = '#ffd700';
    ctx.font = 'bold 20px "Trebuchet MS", sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('Hi-Res AUDIO', width / 2, badgeY + badgeH / 2 + 2);

    // 3. Draw Album Art (Original Image)
    const artSize = 640;
    const artX = (width - artSize) / 2;
    const artY = 140;

    const scale = Math.max(artSize / originalImg.width, artSize / originalImg.height);
    const sw = artSize / scale;
    const sh = artSize / scale;
    const sx = (originalImg.width - sw) / 2;
    const sy = (originalImg.height - sh) / 2;

    // Album shadow
    ctx.save();
    drawRoundRect(ctx, artX, artY, artSize, artSize, 30);
    ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
    ctx.shadowBlur = 40;
    ctx.shadowOffsetY = 20;
    ctx.fill();
    ctx.restore();

    // Album cover clipping
    ctx.save();
    drawRoundRect(ctx, artX, artY, artSize, artSize, 30);
    ctx.clip();
    ctx.drawImage(originalImg, sx, sy, sw, sh, artX, artY, artSize, artSize);
    ctx.restore();

    // 4. Draw Track Info
    ctx.fillStyle = '#ffffff';
    let fontSize = 46;
    ctx.font = `bold ${fontSize}px "Segoe UI", sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'alphabetic';
    
    // Scale down text if too wide
    const maxTextW = artSize - 40;
    while(ctx.measureText(title).width > maxTextW && fontSize > 24) {
        fontSize -= 2;
        ctx.font = `bold ${fontSize}px "Segoe UI", sans-serif`;
    }
    ctx.fillText(title, width / 2, artY + artSize + 90);

    ctx.fillStyle = '#b3b3b3';
    let artistFontSize = 32;
    ctx.font = `${artistFontSize}px "Segoe UI", sans-serif`;
    while(ctx.measureText(artist).width > maxTextW && artistFontSize > 18) {
        artistFontSize -= 2;
        ctx.font = `${artistFontSize}px "Segoe UI", sans-serif`;
    }
    ctx.fillText(artist, width / 2, artY + artSize + 140);

    // 5. Draw Progress Timeline
    const waveX = artX;
    const waveW = artSize;
    const progY = 1000;

    ctx.fillStyle = 'rgba(255,255,255,0.2)';
    drawRoundRect(ctx, waveX, progY, waveW, 6, 3);
    ctx.fill();

    ctx.fillStyle = themeColor;
    drawRoundRect(ctx, waveX, progY, waveW * 0.35, 6, 3);
    ctx.fill();

    ctx.beginPath();
    ctx.arc(waveX + waveW * 0.35, progY + 3, 9, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = '#fff';
    ctx.beginPath();
    ctx.arc(waveX + waveW * 0.35, progY + 3, 4, 0, Math.PI * 2);
    ctx.fill();

    ctx.fillStyle = '#a0a0a0';
    ctx.font = '16px "Segoe UI", sans-serif';
    ctx.textAlign = 'left';
    ctx.fillText('01:24', waveX, progY + 30);
    ctx.textAlign = 'right';
    ctx.fillText('03:45', waveX + waveW, progY + 30);

    // 6. Audio Waveform / Spectrogram Visualization 
    const waveY = progY - 110;
    const waveH = 70;
    let waveformData = new Array(waveW).fill(0);

    // Try parsing provided real audio file if available
    if (audioUrl) {
        try {
            const response = await fetch(audioUrl);
            const arrayBuffer = await response.arrayBuffer();
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const audioBuffer = await new Promise((resolve, reject) => {
                const p = audioContext.decodeAudioData(arrayBuffer, resolve, reject);
                if (p) p.then(resolve).catch(reject); // Promise-based or Callback-based compliance
            });

            const channelData = audioBuffer.getChannelData(0);
            const step = Math.ceil(channelData.length / waveW);
            
            for (let i = 0; i < waveW; i++) {
                let min = 1.0, max = -1.0;
                let start = i * step;
                let end = Math.min((i + 1) * step, channelData.length);
                for (let j = start; j < end; j++) {
                    if (channelData[j] < min) min = channelData[j];
                    if (channelData[j] > max) max = channelData[j];
                }
                waveformData[i] = Math.max(Math.abs(min), Math.abs(max));
            }

            // Simple smoothing kernel
            let smoothed = new Array(waveW).fill(0);
            for(let i = 0; i < waveW; i++) {
                let sum = 0, count = 0;
                for (let k = -2; k <= 2; k++) {
                    if (i + k >= 0 && i + k < waveW) {
                        sum += waveformData[i + k];
                        count++;
                    }
                }
                smoothed[i] = sum / count;
            }
            waveformData = smoothed;
        } catch (e) {
            console.warn("Could not load audio source. Resorting to HIFI visualizer baseline.", e);
        }
    }

    // Dynamic HIFI aesthetic fake generation fallback 
    if (!waveformData.some(v => v > 0)) {
        let phase1 = Math.random() * Math.PI;
        let phase2 = Math.random() * Math.PI;
        for (let i = 0; i < waveW; i++) {
            let pos = i / waveW; 
            let env = 1 - Math.pow(Math.abs(pos - 0.5) * 2, 2); 
            let noise = (Math.random() * 0.4) + 0.6;
            let wave = Math.abs(
                Math.sin(pos * 50 + phase1) * 0.4 +
                Math.cos(pos * 20 + phase2) * 0.4 +
                Math.sin(pos * 100) * 0.2
            );
            waveformData[i] = wave * noise * Math.max(0, env);
        }
    }

    // Actually Draw EQ Visualizer Bars
    ctx.lineWidth = 3.5;
    ctx.lineCap = 'round';
    ctx.strokeStyle = themeColor;

    for (let i = 0; i < waveW; i += 7) {
        let amp = waveformData[i] || 0.02;
        amp = Math.pow(amp, 0.8) * 1.5; 
        let h = Math.max(4, Math.min(amp * waveH, waveH)); 

        ctx.beginPath();
        ctx.moveTo(waveX + i, waveY + waveH/2 - h/2);
        ctx.lineTo(waveX + i, waveY + waveH/2 + h/2);
        ctx.stroke();
    }

    // 7. Draw Base Playback UI Controls
    const controlsY = 1110;
    ctx.fillStyle = '#ffffff';

    // Play/Pause Big Round
    ctx.beginPath();
    ctx.arc(width/2, controlsY, 40, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = '#000000';
    ctx.beginPath();
    ctx.moveTo(width/2 - 12, controlsY - 16);
    ctx.lineTo(width/2 + 18, controlsY);
    ctx.lineTo(width/2 - 12, controlsY + 16);
    ctx.fill();

    ctx.fillStyle = '#ffffff';
    
    // Prev Track
    const prevX = width/2 - 110;
    ctx.beginPath();
    ctx.moveTo(prevX + 10, controlsY - 14);
    ctx.lineTo(prevX - 12, controlsY);
    ctx.lineTo(prevX + 10, controlsY + 14);
    ctx.fill();
    ctx.fillRect(prevX - 17, controlsY - 14, 4, 28);

    // Next Track
    const nextX = width/2 + 110;
    ctx.beginPath();
    ctx.moveTo(nextX - 10, controlsY - 14);
    ctx.lineTo(nextX + 12, controlsY);
    ctx.lineTo(nextX - 10, controlsY + 14);
    ctx.fill();
    ctx.fillRect(nextX + 13, controlsY - 14, 4, 28);

    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 Audio To Image Converter creates professional, high-fidelity music player visualizations based on your album art and audio files. By combining an uploaded image with audio metadata (such as track title and artist name), the tool generates a stylized graphic featuring a blurred background, a centered album cover, and a simulated playback interface. If an audio URL is provided, the tool can generate an accurate waveform or spectrogram visualization, making it an ideal resource for musicians, podcasters, and content creators looking to create high-quality promotional assets or social media posts for their music.

Leave a Reply

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