Please bookmark this page to avoid losing your image tool!

Image Sound Effects Audio Creator

(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.
/**
 * Creates an audio representation of an image through a process called sonification.
 * It scans the image from left to right, treating the vertical axis as a frequency
 * spectrum and pixel brightness as amplitude. The result is an audio file that can be played.
 *
 * @param {Image} originalImg The input JavaScript Image object.
 * @param {number} duration The desired length of the audio in seconds. Default is 5.
 * @param {number} minFreq The lowest frequency (in Hz) mapped to the bottom of the image. Default is 220 (A3).
 * @param {number} maxFreq The highest frequency (in Hz) mapped to the top of the image. Default is 1200.
 * @param {string} waveType The shape of the audio wave, affecting the timbre. Options: 'sine', 'square', 'sawtooth', 'triangle'. Default is 'sine'.
 * @returns {Promise<HTMLAudioElement>} A promise that resolves with an HTML <audio> element containing the generated sound.
 */
async function processImage(originalImg, duration = 5, minFreq = 220, maxFreq = 1200, waveType = 'sine') {

    /**
     * Converts an AudioBuffer to a WAV file Blob.
     * @param {AudioBuffer} buffer The audio buffer to convert.
     * @returns {Blob} A blob representing the WAV file.
     */
    const bufferToWav = (buffer) => {
        const numOfChan = buffer.numberOfChannels;
        const length = buffer.length * numOfChan * 2 + 44;
        const bufferArr = new ArrayBuffer(length);
        const view = new DataView(bufferArr);
        let pos = 0;

        const writeString = (view, offset, string) => {
            for (let i = 0; i < string.length; i++) {
                view.setUint8(offset + i, string.charCodeAt(i));
            }
        };

        // RIFF header
        writeString(view, pos, 'RIFF'); pos += 4;
        view.setUint32(pos, length - 8, true); pos += 4;
        writeString(view, pos, 'WAVE'); pos += 4;

        // FMT sub-chunk
        writeString(view, pos, 'fmt '); pos += 4;
        view.setUint32(pos, 16, true); pos += 4;
        view.setUint16(pos, 1, true); pos += 2;
        view.setUint16(pos, numOfChan, true); pos += 2;
        view.setUint32(pos, buffer.sampleRate, true); pos += 4;
        view.setUint32(pos, buffer.sampleRate * 2 * numOfChan, true); pos += 4;
        view.setUint16(pos, numOfChan * 2, true); pos += 2;
        view.setUint16(pos, 16, true); pos += 2;

        // Data sub-chunk
        writeString(view, pos, 'data'); pos += 4;
        view.setUint32(pos, length - pos - 4, true); pos += 4;

        // Write samples
        const channelData = buffer.getChannelData(0); // Assuming mono
        for (let i = 0; i < channelData.length; i++) {
            const sample = Math.max(-1, Math.min(1, channelData[i]));
            view.setInt16(pos, sample < 0 ? sample * 32768 : sample * 32767, true);
            pos += 2;
        }

        return new Blob([view], { type: 'audio/wav' });
    };

    /**
     * Generates a waveform value for a given phase and type.
     * @param {string} type - 'sine', 'square', 'sawtooth', 'triangle'.
     * @param {number} phase - The current phase of the wave.
     * @returns {number} The wave value (-1 to 1).
     */
    const getWaveValue = (type, phase) => {
        switch (type.toLowerCase()) {
            case 'square':
                return Math.sign(Math.sin(phase));
            case 'sawtooth':
                return 2 * (phase / (2 * Math.PI) - Math.floor(0.5 + phase / (2 * Math.PI)));
            case 'triangle':
                 return (2 / Math.PI) * Math.asin(Math.sin(phase));
            case 'sine':
            default:
                return Math.sin(phase);
        }
    };
    
    return new Promise((resolve, reject) => {
        try {
            // 1. Setup Canvas and scale image for performance
            // For performance, we cap the width and scale the image down if necessary.
            const MAX_WIDTH = 800;
            const aspectRatio = originalImg.naturalHeight / originalImg.naturalWidth;
            const width = Math.min(originalImg.naturalWidth, MAX_WIDTH);
            const height = Math.floor(width * aspectRatio);

            const canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(originalImg, 0, 0, width, height);
            const imageData = ctx.getImageData(0, 0, width, height);
            const data = imageData.data;

            // 2. Setup Web Audio API
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            const audioCtx = new AudioContext();
            const sampleRate = audioCtx.sampleRate;
            const numSamples = Math.floor(duration * sampleRate);
            const audioBuffer = audioCtx.createBuffer(1, numSamples, sampleRate); // 1 = mono channel
            const channelData = audioBuffer.getChannelData(0);

            let maxAmplitude = 0;

            // 3. Main sonification loop (this can be computationally intensive)
            for (let i = 0; i < numSamples; i++) {
                const time = i / sampleRate;
                const x = Math.min(width - 1, Math.floor((i / numSamples) * width));
                
                let sampleValue = 0;

                for (let y = 0; y < height; y++) {
                    const pixelIndex = (y * width + x) * 4;
                    const r = data[pixelIndex];
                    const g = data[pixelIndex + 1];
                    const b = data[pixelIndex + 2];
                    const brightness = (r + g + b) / (3 * 255);

                    if (brightness > 0.05) { // Threshold to ignore pure black
                        // Map y-position to frequency (invert y so top is high freq)
                        const freq = minFreq + ((height - 1 - y) / (height - 1)) * (maxFreq - minFreq);
                        const phase = 2 * Math.PI * freq * time;
                        sampleValue += getWaveValue(waveType, phase) * brightness;
                    }
                }
                channelData[i] = sampleValue;
                if (Math.abs(sampleValue) > maxAmplitude) {
                    maxAmplitude = Math.abs(sampleValue);
                }
            }

            // 4. Normalize the audio to prevent clipping and use full dynamic range
            if (maxAmplitude > 1.0) { // Only normalize if clipping would occur
                for (let i = 0; i < numSamples; i++) {
                    channelData[i] /= maxAmplitude;
                }
            }
            
            // 5. Convert buffer to WAV and create an audio element
            const wavBlob = bufferToWav(audioBuffer);
            const audioUrl = URL.createObjectURL(wavBlob);
            const audioElement = document.createElement('audio');
            audioElement.controls = true;
            audioElement.src = audioUrl;
            
            // 6. Clean up and resolve
            audioCtx.close();
            resolve(audioElement);

        } catch (error) {
            console.error("Error processing image into audio:", error);
            const errorElement = document.createElement('p');
            errorElement.textContent = 'Could not generate audio. See console for details.';
            errorElement.style.color = 'red';
            reject(errorElement);
        }
    });
}

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 Sound Effects Audio Creator is a unique tool that converts visual information from images into audio representations through a process called sonification. By analyzing the brightness of pixels in an image and mapping them to different frequencies and amplitudes, this tool generates sound that corresponds to the image’s features. Users can customize various parameters including the audio duration, frequency range, and waveform type to create distinct auditory experiences. This tool is useful for artists, educators, and researchers interested in exploring the intersection of visual art and sound, as well as for those looking to create immersive experiences or novel interpretations of images in sound form.

Leave a Reply

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