Please bookmark this page to avoid losing your image tool!

Image Cloudy Filter Application

(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, desaturationInput = 0.4, brightnessInput = 20, contrastInput = -20, coolShiftInput = 10) {
    // Ensure parameters are numbers. Default values are used if inputs are undefined.
    // Number() conversion handles cases where 'null' or a string representation of a number is passed.
    const desaturation = Number(desaturationInput);
    const brightness = Number(brightnessInput);
    const contrast = Number(contrastInput); // Expected range: -100 to 100
    const coolShift = Number(coolShiftInput); // Expected range: positive for cool, negative for warm (e.g. 0 to 50 for cool)

    const canvas = document.createElement('canvas');
    // Use { willReadFrequently: true } for potential performance optimization if supported/effective.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Set canvas dimensions to the intrinsic dimensions of the image
    // originalImg should be a loaded image for naturalWidth/Height to be reliable
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    // If canvas has no area, no processing can be done. Return empty canvas.
    if (canvas.width === 0 || canvas.height === 0) {
        return canvas;
    }

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    // --- Parameter Pre-processing ---

    // Clamp desaturation to the 0-1 range for predictable behavior
    const clampedDesaturation = Math.max(0, Math.min(1, desaturation));

    // Clamp contrast to a typical -100 to 100 range for the formula
    // Values outside this might lead to extreme or undesired effects
    const clampedContrast = Math.max(-100, Math.min(100, contrast));
    // Calculate contrast factor. Formula: (259 * (C + 255)) / (255 * (259 - C))
    // where C is the contrast value. If C=0, factor=1 (no change).
    // If C=-255, factor=0. If C=255, factor is effectively infinite (clamped by pixel values).
    // Our clampedContrast ensures C is between -100 and 100.
    let contrastFactor = 1; // Default to no contrast change
    if (clampedContrast !== 0) { // Avoid division by zero if 259 - clampedContrast is 0, though not an issue with [-100, 100]
         contrastFactor = (259 * (clampedContrast + 255)) / (255 * (259 - clampedContrast));
    }


    // --- Pixel Manipulation Loop ---
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i+1];
        let b = data[i+2];

        // 1. Desaturation
        // If desaturation is 0, clampedDesaturation is 0, original colors are preserved.
        // If desaturation is 1, clampedDesaturation is 1, image becomes grayscale.
        // Formula: R' = R * (1-d) + L * d, where L is luminance.
        if (clampedDesaturation > 0) { // Apply only if desaturation is effective
            const lum = 0.299 * r + 0.587 * g + 0.114 * b; // Luminance
            r = r * (1 - clampedDesaturation) + lum * clampedDesaturation;
            g = g * (1 - clampedDesaturation) + lum * clampedDesaturation;
            b = b * (1 - clampedDesaturation) + lum * clampedDesaturation;
        }

        // 2. Contrast Adjustment
        // Formula: C' = factor * (C - 128) + 128
        // Applied only if contrastInput was non-zero to potentially save computation,
        // though factor=1 would yield original values.
        if (contrastInput !== 0) {
            r = contrastFactor * (r - 128) + 128;
            g = contrastFactor * (g - 128) + 128;
            b = contrastFactor * (b - 128) + 128;
        }
        
        // 3. Brightness Adjustment
        // R' = R + brightness
        if (brightness !== 0) { // Apply only if brightness adjustment is non-zero
            r += brightness;
            g += brightness;
            b += brightness;
        }

        // 4. Cool Shift (Tinting)
        // Positive coolShift adds blue and reduces red. Negative would do the opposite (warm shift).
        if (coolShift !== 0) {
            r -= coolShift * 0.5; // Reduce red component
            // Optionally, green could be adjusted too: g -= coolShift * 0.25;
            b += coolShift;        // Increase blue component
        }

        // Clamp final RGB values to the valid [0, 255] range
        data[i]   = Math.max(0, Math.min(255, Math.round(r)));
        data[i+1] = Math.max(0, Math.min(255, Math.round(g)));
        data[i+2] = Math.max(0, Math.min(255, Math.round(b)));
        // Alpha channel (data[i+3]) is preserved
    }

    // Write the modified pixel data back to 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 Cloudy Filter Application allows users to apply a soft, cloudy effect to their images. By adjusting parameters such as desaturation, brightness, contrast, and color shifts, users can customize the look of their photos to create a tranquil and atmospheric vibe. This tool is useful for photographers, graphic designers, and social media users looking to enhance their images with a unique filter that evokes a sense of calm and clarity. Common use cases include preparing images for social media posts, creating backgrounds for digital art, or simply enhancing personal photo collections.

Leave a Reply

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