Please bookmark this page to avoid losing your image tool!

Image Voice Pattern Filter Effect Tool

(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, amplitude = 50, frequency = 5, waveType = "sine", direction = "vertical") {
    // Helper function for smoothing random patterns
    function _movingAverageSmooth(arr, windowSizeInput) {
        if (!arr || arr.length === 0) return [];
        
        // Ensure windowSize is at least 1 and odd for symmetry, and not larger than array length
        let windowSize = Math.max(1, Math.floor(windowSizeInput));
        if (windowSize % 2 === 0) windowSize++; // Make it odd
        windowSize = Math.min(windowSize, arr.length);


        if (windowSize <= 1) return [...arr]; // No smoothing or return a copy

        const result = new Array(arr.length);
        const halfWindow = Math.floor(windowSize / 2);

        for (let i = 0; i < arr.length; i++) {
            let sum = 0;
            let count = 0;
            for (let j = Math.max(0, i - halfWindow); j <= Math.min(arr.length - 1, i + halfWindow); j++) {
                sum += arr[j];
                count++;
            }
            result[i] = (count > 0) ? (sum / count) : arr[i]; // Fallback to original if count is somehow 0
        }
        return result;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    const w = originalImg.naturalWidth || originalImg.width;
    const h = originalImg.naturalHeight || originalImg.height;
    canvas.width = w;
    canvas.height = h;

    if (w === 0 || h === 0) { // Handle cases with invalid image dimensions
        return canvas; // Return empty canvas
    }

    ctx.drawImage(originalImg, 0, 0, w, h);
    const imageData = ctx.getImageData(0, 0, w, h);
    const data = imageData.data;

    const patternLength = (direction === "vertical") ? w : h;
    if (patternLength === 0) { // Should be caught by w/h check, but defensive
         ctx.putImageData(imageData, 0, 0); // No changes if no length for pattern
         return canvas;
    }
    
    const pattern = new Array(patternLength);
    let trueFrequency = Math.max(0.1, frequency); // Ensure frequency is positive to avoid division by zero

    if (waveType === "sine") {
        const period = patternLength / trueFrequency;
        for (let i = 0; i < patternLength; i++) {
            // Generates values between 0 and 1
            if (period === 0) { // Should not happen with trueFrequency > 0
                 pattern[i] = 0.5;
            } else {
                 pattern[i] = (Math.sin((i / period) * 2 * Math.PI) + 1) / 2;
            }
        }
    } else if (waveType === "random") {
        let currentValue = 0.5;
        const maxStep = 0.15; // Max random change per step
        for (let i = 0; i < patternLength; i++) {
            pattern[i] = currentValue;
            currentValue += (Math.random() - 0.5) * 2 * maxStep;
            currentValue = Math.max(0, Math.min(1, currentValue)); // Clamp to 0-1
        }
        
        const smoothWindowSize = Math.max(3, Math.floor(patternLength / (trueFrequency * 2)));
        const smoothedPattern = _movingAverageSmooth(pattern, smoothWindowSize);
        
        // Normalize smoothedPattern to ensure it spans 0-1 range
        let minVal = smoothedPattern[0];
        let maxVal = smoothedPattern[0];
        for(let i = 1; i < patternLength; i++) {
            if (smoothedPattern[i] < minVal) minVal = smoothedPattern[i];
            if (smoothedPattern[i] > maxVal) maxVal = smoothedPattern[i];
        }

        if (maxVal === minVal) { // If pattern is flat after smoothing
             for(let i=0; i<patternLength; i++) pattern[i] = 0.5;
        } else {
            for (let i = 0; i < patternLength; i++) {
                pattern[i] = (smoothedPattern[i] - minVal) / (maxVal - minVal);
            }
        }
    } else { // Default to sine if waveType is unknown
        const period = patternLength / trueFrequency;
        for (let i = 0; i < patternLength; i++) {
             if (period === 0) {
                 pattern[i] = 0.5;
             } else {
                 pattern[i] = (Math.sin((i / period) * 2 * Math.PI) + 1) / 2;
             }
        }
    }

    for (let y = 0; y < h; y++) {
        for (let x = 0; x < w; x++) {
            const R_idx = (y * w + x) * 4;
            const G_idx = R_idx + 1;
            const B_idx = R_idx + 2;
            // Alpha (A_idx = R_idx + 3) is not modified by this effect

            let patternValue;
            if (direction === "vertical") {
                patternValue = pattern[x];
            } else { // horizontal
                patternValue = pattern[y];
            }

            // Calculate brightness change:
            // patternValue (0 to 1) is mapped to a brightness change factor.
            // (patternValue - 0.5) gives -0.5 to 0.5.
            // Multiply by 2 gives -1 to 1.
            // Multiply by amplitude gives -amplitude to +amplitude.
            const brightnessChange = (patternValue - 0.5) * 2 * amplitude;

            data[R_idx] = Math.max(0, Math.min(255, data[R_idx] + brightnessChange));
            data[G_idx] = Math.max(0, Math.min(255, data[G_idx] + brightnessChange));
            data[B_idx] = Math.max(0, Math.min(255, data[B_idx] + brightnessChange));
        }
    }

    ctx.putImageData(imageData, 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 Image Voice Pattern Filter Effect Tool allows users to apply a unique visual effect to images by altering their brightness based on wave patterns. Users can choose between different wave types (sine or random) and set parameters like amplitude and frequency to customize the filter’s intensity and style. This tool can be useful for creating artistic images, enhancing visual presentations, or generating interesting graphics for social media posts by adding a dynamic and abstract appearance to existing images.

Leave a Reply

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