Please bookmark this page to avoid losing your image tool!

Image Ethereal Fog Filter

(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, fogBaseColorStr = "220,220,240", fogOpacity = 0.4, fogNoiseStrength = 0.15) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Determine image dimensions. Use naturalWidth/Height for HTMLImageElement if available,
    // otherwise fallback to width/height (e.g., for CanvasElement or ImageBitmap).
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    canvas.width = imgWidth;
    canvas.height = imgHeight;
    
    // Handle cases where image might not be fully loaded or has 0 dimensions
    if (imgWidth === 0 || imgHeight === 0) {
        console.warn("Image Ethereal Fog Filter: Original image has zero width or height. Returning an empty canvas.");
        return canvas; // Return an empty canvas
    }

    // Draw the original image onto the canvas
    // The third and fourth parameters for drawImage (dest width/height) ensure it's drawn at the intended processing size.
    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    // --- Parameter parsing and validation ---

    // Parse fogBaseColorStr (e.g., "R,G,B")
    let parsedFogR = 220, parsedFogG = 220, parsedFogB = 240; // Default fog color values
    try {
        if (typeof fogBaseColorStr !== 'string') {
            throw new Error("fogBaseColorStr must be a string.");
        }
        const parts = fogBaseColorStr.split(',').map(s => {
            const num = parseInt(s.trim(), 10);
            // Check if num is a valid color component (0-255)
            if (isNaN(num) || num < 0 || num > 255) {
                throw new Error(`Invalid color component found: '${s.trim()}'`);
            }
            return num;
        });
        if (parts.length === 3) {
            [parsedFogR, parsedFogG, parsedFogB] = parts;
        } else {
            throw new Error("Color string must have 3 components (R,G,B).");
        }
    } catch (e) {
        console.warn(`Image Ethereal Fog Filter: Invalid fogBaseColorStr "${fogBaseColorStr}". Error: ${e.message}. Using default color (${parsedFogR},${parsedFogG},${parsedFogB}).`);
        // Defaults are already set ([220,220,240]), so just log warning and proceed.
    }

    // Validate fogOpacity
    let validFogOpacity = typeof fogOpacity === 'number' ? fogOpacity : parseFloat(fogOpacity);
    if (isNaN(validFogOpacity) || validFogOpacity < 0 || validFogOpacity > 1) {
        console.warn(`Image Ethereal Fog Filter: Invalid fogOpacity "${fogOpacity}". Must be a number between 0 and 1. Using default 0.4.`);
        validFogOpacity = 0.4; // Default value for fogOpacity
    }

    // Validate fogNoiseStrength
    let validFogNoiseStrength = typeof fogNoiseStrength === 'number' ? fogNoiseStrength : parseFloat(fogNoiseStrength);
    if (isNaN(validFogNoiseStrength) || validFogNoiseStrength < 0 || validFogNoiseStrength > 1) {
        console.warn(`Image Ethereal Fog Filter: Invalid fogNoiseStrength "${fogNoiseStrength}". Must be a number between 0 and 1. Using default 0.15.`);
        validFogNoiseStrength = 0.15; // Default value for fogNoiseStrength
    }
    
    // If fog effect is negligible (e.g., opacity and noise are zero),
    // no need to process pixels, return the canvas with the original image.
    if (validFogOpacity <= 0 && validFogNoiseStrength <= 0) {
        return canvas; 
    }

    const imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    const data = imageData.data; // This is a Uint8ClampedArray

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];     // Original red
        const g = data[i+1];   // Original green
        const b = data[i+2];   // Original blue
        // data[i+3] is the original alpha, which will remain untouched by this filter.

        let noise = 0;
        if (validFogNoiseStrength > 0) {
             // Generates noise in the range: [-validFogNoiseStrength, +validFogNoiseStrength]
             noise = (Math.random() * 2 - 1) * validFogNoiseStrength;
        }

        let effectiveOpacity = validFogOpacity + noise;
        // Clamp effectiveOpacity to the valid [0, 1] range
        effectiveOpacity = Math.max(0, Math.min(1, effectiveOpacity)); 

        // Only apply blending if there's some fog opacity
        if (effectiveOpacity > 0) { 
            // Blend original pixel color with the fog color
            // Formula: NewColor = OriginalColor * (1 - Opacity) + FogColor * Opacity
            data[i]   = Math.round(r * (1 - effectiveOpacity) + parsedFogR * effectiveOpacity);
            data[i+1] = Math.round(g * (1 - effectiveOpacity) + parsedFogG * effectiveOpacity);
            data[i+2] = Math.round(b * (1 - effectiveOpacity) + parsedFogB * effectiveOpacity);
            // Since r,g,b and parsedFogR,G,B are in [0,255] and effectiveOpacity is in [0,1],
            // the results will be within [0,255] after Math.round().
            // Uint8ClampedArray will also clamp values automatically.
        }
    }

    // Put the modified pixel data back onto the canvas
    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 Ethereal Fog Filter is a tool designed to apply a dreamy fog effect to your images. By adjusting parameters such as fog color, opacity, and noise strength, users can transform their photos to evoke a softer, misty aesthetic. This filter is ideal for enhancing landscape photography, adding a mystical touch to portraits, or creating atmospheric backgrounds for digital art. Whether for personal projects or professional presentations, the tool enables users to create visually captivating images with ease.

Leave a Reply

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