Please bookmark this page to avoid losing your image tool!

Music Sound Wave Image 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,
    backgroundColor = "#000000",
    lineColor = "#ffffff",
    style = "original_colors",
    direction = "horizontal",
    waveType = "sine",
    lineSpacing = 15,
    amplitude = 12,
    frequency = 0.5,
    thickness = 2,
    invertAmplitude = 0
) {
    lineSpacing = Math.max(2, parseFloat(lineSpacing) || 15);
    amplitude = parseFloat(amplitude) || 12;
    frequency = parseFloat(frequency) || 0.5;
    thickness = parseFloat(thickness) || 2;
    invertAmplitude = Number(invertAmplitude) || 0;

    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    // Create offscreen canvas to retrieve image pixel data
    const offscreen = document.createElement('canvas');
    offscreen.width = width;
    offscreen.height = height;
    const offCtx = offscreen.getContext('2d');
    offCtx.drawImage(originalImg, 0, 0);
    const imgData = offCtx.getImageData(0, 0, width, height).data;

    // Main canvas for final output
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Fill the background color
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, width, height);

    // Wave canvas to hold the string paths
    const waveCanvas = document.createElement('canvas');
    waveCanvas.width = width;
    waveCanvas.height = height;
    const waveCtx = waveCanvas.getContext('2d');

    waveCtx.strokeStyle = style === 'original_colors' ? '#ffffff' : lineColor;
    waveCtx.lineWidth = thickness;
    waveCtx.lineJoin = waveType === 'sine' ? 'round' : 'miter';
    waveCtx.lineCap = waveType === 'sine' ? 'round' : 'butt';

    let waveFunc;
    if (waveType === 'square') {
        waveFunc = (val) => Math.sin(val) >= 0 ? 1 : -1;
    } else if (waveType === 'triangle') {
        waveFunc = (val) => Math.asin(Math.sin(val)) / (Math.PI / 2);
    } else {
        waveFunc = (val) => Math.sin(val);
    }

    if (direction === "horizontal" || direction === "both") {
        for (let y = lineSpacing / 2; y < height; y += lineSpacing) {
            waveCtx.beginPath();
            waveCtx.moveTo(0, y);
            let py = Math.floor(y);
            if (py >= height) py = height - 1;
            let yOffset = py * width;

            for (let x = 0; x < width; x++) {
                let idx = (yOffset + x) * 4;
                let a = imgData[idx + 3] / 255;
                
                let brightness;
                if (a === 1) {
                    brightness = (0.299 * imgData[idx] + 0.587 * imgData[idx + 1] + 0.114 * imgData[idx + 2]) / 255;
                } else if (a === 0) {
                    brightness = 1; // treat fully transparent background as white
                } else {
                    let r = imgData[idx] * a + 255 * (1 - a);
                    let g = imgData[idx + 1] * a + 255 * (1 - a);
                    let b = imgData[idx + 2] * a + 255 * (1 - a);
                    brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
                }

                let intensity = invertAmplitude ? brightness : (1 - brightness);
                let dy = waveFunc(x * frequency) * amplitude * intensity;
                waveCtx.lineTo(x, y + dy);
            }
            waveCtx.stroke();
        }
    }

    if (direction === "vertical" || direction === "both") {
        for (let x = lineSpacing / 2; x < width; x += lineSpacing) {
            waveCtx.beginPath();
            waveCtx.moveTo(x, 0);
            let px = Math.floor(x);
            if (px >= width) px = width - 1;

            for (let y = 0; y < height; y++) {
                let idx = (y * width + px) * 4;
                let a = imgData[idx + 3] / 255;
                
                let brightness;
                if (a === 1) {
                    brightness = (0.299 * imgData[idx] + 0.587 * imgData[idx + 1] + 0.114 * imgData[idx + 2]) / 255;
                } else if (a === 0) {
                    brightness = 1; // treat fully transparent background as white
                } else {
                    let r = imgData[idx] * a + 255 * (1 - a);
                    let g = imgData[idx + 1] * a + 255 * (1 - a);
                    let b = imgData[idx + 2] * a + 255 * (1 - a);
                    brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
                }

                let intensity = invertAmplitude ? brightness : (1 - brightness);
                let dx = waveFunc(y * frequency) * amplitude * intensity;
                waveCtx.lineTo(x + dx, y);
            }
            waveCtx.stroke();
        }
    }

    // Embed the original colors inside the structural sound wave paths using source-in
    if (style === 'original_colors') {
        waveCtx.globalCompositeOperation = 'source-in';
        waveCtx.drawImage(originalImg, 0, 0);
    }

    // Blend the newly composed sound wave into the final canvas
    ctx.drawImage(waveCanvas, 0, 0);

    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 Music Sound Wave Image Generator transforms standard images into stylized visual representations resembling sound waves. By analyzing the brightness and color data of an uploaded image, the tool generates wave patterns—such as sine, square, or triangle waves—that follow the contours and intensity of the original picture. Users can customize the output by adjusting parameters like wave direction (horizontal, vertical, or both), line spacing, amplitude, frequency, and line thickness. This tool is ideal for creating unique digital art, personalized music album covers, social media graphics, or artistic wallpapers that blend photographic elements with abstract waveform aesthetics.

Leave a Reply

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