Please bookmark this page to avoid losing your image tool!

Image To Sound Effects Audio Mp3 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, durationSec = 5, minFreqHz = 100, maxFreqHz = 8000, verticalBands = 50) {
    const duration = parseFloat(durationSec) || 5;
    const minFreq = parseFloat(minFreqHz) || 100;
    const maxFreq = parseFloat(maxFreqHz) || 8000;
    const H = parseInt(verticalBands) || 50;
    const sampleRate = 44100;
    const totalSamples = Math.floor(sampleRate * duration);

    // 1. Process Image to extract Brightness Map (Inverse Spectrogram Data)
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const W = Math.max(1, Math.round((originalImg.width / originalImg.height) * H));
    canvas.width = W;
    canvas.height = H;
    ctx.drawImage(originalImg, 0, 0, W, H);
    
    // Read brightness for each pixel (Log intensity)
    const imgData = ctx.getImageData(0, 0, W, H).data;
    const brightness = Array.from({ length: W }, () => new Float32Array(H));
    
    for (let y = 0; y < H; y++) {
        for (let x = 0; x < W; x++) {
            const idx = (y * W + x) * 4;
            const r = imgData[idx];
            const g = imgData[idx + 1];
            const b = imgData[idx + 2];
            // Compute luminance (0 to 1)
            brightness[x][y] = (0.299 * r + 0.587 * g + 0.114 * b) / 255.0;
        }
    }

    // 2. Synthesize Audio
    const samples = new Float32Array(totalSamples);
    const twoPi = 2 * Math.PI;

    // Frequencies (Logarithmic scale: Top of image = high freq, Bottom = low freq)
    const freqs = new Float32Array(H);
    for (let y = 0; y < H; y++) {
        const percent = (H - 1 - y) / (H - 1 || 1);
        freqs[y] = minFreq * Math.pow(maxFreq / minFreq, percent);
    }

    // Generate sine waves per row and accumulate into the sample buffer
    for (let y = 0; y < H; y++) {
        const f = freqs[y];
        let phase = 0;
        const phaseInc = (twoPi * f) / sampleRate;

        for (let x = 0; x < W; x++) {
            const b1 = brightness[x][y];
            const b2 = x < W - 1 ? brightness[x + 1][y] : 0;
            const start = Math.floor((x / W) * totalSamples);
            const end = Math.min(totalSamples, Math.floor(((x + 1) / W) * totalSamples));
            const length = end - start;

            for (let i = 0; i < length; i++) {
                const pct = i / length;
                const amp = b1 + (b2 - b1) * pct; // Linear interpolate brightness to avoid clicks
                samples[start + i] += amp * Math.sin(phase);
                phase += phaseInc;
            }
        }
    }

    // 3. Normalize audio and convert to Int16
    let maxVal = 0;
    for (let i = 0; i < totalSamples; i++) {
        const absVal = Math.abs(samples[i]);
        if (absVal > maxVal) maxVal = absVal;
    }

    const intSamples = new Int16Array(totalSamples);
    const volumeMultiplier = maxVal > 0 ? (32767 * 0.9) / maxVal : 0;

    for (let i = 0; i < totalSamples; i++) {
        intSamples[i] = Math.max(-32768, Math.min(32767, samples[i] * volumeMultiplier));
    }

    // 4. Encode to MP3 (or gracefully fallback to WAV)
    const loadLameJS = () => new Promise((resolve, reject) => {
        if (window.lamejs) return resolve(window.lamejs);
        const script = document.createElement('script');
        script.src = "https://cdnjs.cloudflare.com/ajax/libs/lamejs/1.2.1/lame.min.js";
        script.onload = () => resolve(window.lamejs);
        script.onerror = reject;
        document.head.appendChild(script);
    });

    let audioBlob;
    let extension = "mp3";

    try {
        const lamejs = await loadLameJS();
        const mp3encoder = new lamejs.Mp3Encoder(1, sampleRate, 128); // 1 channel, 44.1kHz, 128kbps
        const mp3Data = [];
        const sampleBlockSize = 1152; // Needs to be a multiple of 576

        for (let i = 0; i < totalSamples; i += sampleBlockSize) {
            const chunk = intSamples.subarray(i, i + sampleBlockSize);
            const mp3buf = mp3encoder.encodeBuffer(chunk);
            if (mp3buf.length > 0) mp3Data.push(mp3buf);
        }
        const mp3buf = mp3encoder.flush();
        if (mp3buf.length > 0) mp3Data.push(mp3buf);

        audioBlob = new Blob(mp3Data, { type: 'audio/mp3' });
    } catch (e) {
        console.warn("Failed to load LameJS MP3 Encoder, falling back to Native WAV.", e);
        extension = "wav";

        // Generate WAV Header & Payload manually
        const buffer = new ArrayBuffer(44 + intSamples.length * 2);
        const view = new DataView(buffer);
        const writeString = (v, offset, string) => {
            for (let i = 0; i < string.length; i++) {
                v.setUint8(offset + i, string.charCodeAt(i));
            }
        };

        writeString(view, 0, 'RIFF');
        view.setUint32(4, 36 + intSamples.length * 2, true);
        writeString(view, 8, 'WAVE');
        writeString(view, 12, 'fmt ');
        view.setUint32(16, 16, true);
        view.setUint16(20, 1, true);
        view.setUint16(22, 1, true);
        view.setUint32(24, sampleRate, true);
        view.setUint32(28, sampleRate * 2, true);
        view.setUint16(32, 2, true);
        view.setUint16(34, 16, true);
        writeString(view, 36, 'data');
        view.setUint32(40, intSamples.length * 2, true);
        
        let offset = 44;
        for (let i = 0; i < intSamples.length; i++, offset += 2) {
            view.setInt16(offset, intSamples[i], true);
        }
        audioBlob = new Blob([view], { type: 'audio/wav' });
    }

    // 5. Build and return User Interface Element
    const container = document.createElement('div');
    container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.gap = '20px';
    container.style.padding = '25px';
    container.style.background = '#f9fafb';
    container.style.border = '1px solid #e5e7eb';
    container.style.borderRadius = '12px';
    container.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)';
    container.style.maxWidth = '400px';
    container.style.margin = '0 auto';

    const titleInfo = document.createElement('h3');
    titleInfo.textContent = "Image to Sound Effects Generator";
    titleInfo.style.margin = '0';
    titleInfo.style.color = '#1f2937';
    container.appendChild(titleInfo);

    // Provide scaled display representation
    const displayImg = new Image();
    displayImg.src = originalImg.src;
    displayImg.style.maxWidth = '100%';
    displayImg.style.maxHeight = '200px';
    displayImg.style.objectFit = 'contain';
    displayImg.style.borderRadius = '8px';
    displayImg.style.border = '1px solid #d1d5db';
    displayImg.style.background = '#000';
    container.appendChild(displayImg);

    const audioUrl = URL.createObjectURL(audioBlob);

    // Audio Player
    const audioEl = document.createElement('audio');
    audioEl.controls = true;
    audioEl.src = audioUrl;
    audioEl.style.width = '100%';
    container.appendChild(audioEl);

    // Download Button
    const downloadLink = document.createElement('a');
    downloadLink.href = audioUrl;
    downloadLink.download = `sonified_image_audio.${extension}`;
    downloadLink.textContent = `Download ${extension.toUpperCase()} Track`;
    downloadLink.style.padding = '12px 24px';
    downloadLink.style.background = '#4F46E5';
    downloadLink.style.color = '#ffffff';
    downloadLink.style.textDecoration = 'none';
    downloadLink.style.borderRadius = '8px';
    downloadLink.style.fontWeight = '600';
    downloadLink.style.transition = 'background 0.2s';
    downloadLink.style.cursor = 'pointer';
    downloadLink.onmouseover = () => downloadLink.style.background = '#4338CA';
    downloadLink.onmouseout  = () => downloadLink.style.background = '#4F46E5';
    
    container.appendChild(downloadLink);

    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 converts images into audio files by translating visual data into sound. It works by analyzing the brightness and structure of an image and mapping those properties to sound frequencies and amplitudes, effectively creating a sonified version of the picture. Users can customize parameters such as audio duration, frequency range, and vertical resolution to influence the resulting sound. This tool is useful for digital artists looking for unique sound textures, researchers exploring data sonification, or creators wanting to transform visual patterns into experimental sound effects and ambient tracks.

Leave a Reply

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