Please bookmark this page to avoid losing your image tool!

Image Underwater 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.
/**
 * Applies an underwater filter to an image.
 * The filter adjusts color channels to simulate underwater light absorption
 * and adds an optional haze effect for murkiness.
 *
 * @param {HTMLImageElement} originalImg - The original Javascript Image object.
 *   It's assumed this image is already loaded (e.g., via `img.onload` or it's an existing DOM image).
 * @param {number} [redMultiplier=0.6] - Multiplier for the red channel.
 *   Values < 1 reduce red (simulating red light absorption underwater), > 1 boost red.
 *   Default is 0.6, significantly reducing red.
 * @param {number} [greenMultiplier=1.1] - Multiplier for the green channel.
 *   Water absorbs green less than red. Default is 1.1, slightly boosting green.
 * @param {number} [blueMultiplier=1.3] - Multiplier for the blue channel.
 *   Blue light penetrates deepest. Default is 1.3, boosting blue.
 * @param {number} [hazeAmount=0.15] - Controls the amount of haze/murkiness (0 to 1).
 *   0 means no haze. 1 means the pixel is fully blended towards the haze color.
 *   Default is 0.15 for a subtle haze.
 * @returns {HTMLCanvasElement} A new canvas element displaying the filtered image.
 */
function processImage(originalImg, redMultiplier = 0.6, greenMultiplier = 1.1, blueMultiplier = 1.3, hazeAmount = 0.15) {
    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } can sometimes optimize repeated getImageData/putImageData calls
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Determine image dimensions. Prioritize natural dimensions for intrinsic size.
    // Fallback to width/height for elements like <canvas> or if natural dimensions aren't available.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // If image dimensions are zero (e.g., image not loaded or invalid),
    // return the empty canvas with a warning.
    if (canvas.width === 0 || canvas.height === 0) {
        console.warn("Image dimensions are 0. The image might not be loaded or is invalid. Returning an empty canvas.");
        return canvas;
    }

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

    // Get pixel data from the canvas.
    // This can be computationally intensive for large images.
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data; // data is a Uint8ClampedArray

    // Define a base color for the haze/murkiness effect
    // This is a desaturated cyan/blue, typical for particulate matter in water
    const hazeColorR = 80;
    const hazeColorG = 100;
    const hazeColorB = 110;

    // Clamp hazeAmount to the range [0, 1] to ensure it behaves as mixing factor
    const clampedHazeAmount = Math.max(0, Math.min(1, hazeAmount));

    // Iterate over each pixel in the ImageData array
    // Each pixel consists of 4 values: R, G, B, A
    for (let i = 0; i < data.length; i += 4) {
        // Get original RGB values
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        // Alpha channel (data[i + 3]) is preserved

        // Apply color channel multipliers for the underwater effect
        let filteredR = r * redMultiplier;
        let filteredG = g * greenMultiplier;
        let filteredB = b * blueMultiplier;

        // Apply haze effect if hazeAmount is greater than 0
        // This blends the current pixel color with the predefined haze color
        if (clampedHazeAmount > 0) {
            filteredR = filteredR * (1 - clampedHazeAmount) + hazeColorR * clampedHazeAmount;
            filteredG = filteredG * (1 - clampedHazeAmount) + hazeColorG * clampedHazeAmount;
            filteredB = filteredB * (1 - clampedHazeAmount) + hazeColorB * clampedHazeAmount;
        }

        // Assign the modified RGB values back to the ImageData
        // The Uint8ClampedArray automatically clamps values to the 0-255 range
        data[i] = filteredR;
        data[i + 1] = filteredG;
        data[i + 2] = filteredB;
        // data[i + 3] (alpha) remains unchanged
    }

    // Put the modified pixel data back onto the canvas
    ctx.putImageData(imageData, 0, 0);

    // Return the canvas with the filtered image
    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 Underwater Filter Application is designed to enhance images by simulating an underwater environment. This tool applies a filter that adjusts the color channels of an image to mimic the effects of light absorption under water, providing a more realistic underwater aesthetic. Users can customize the intensity of the red, green, and blue channels, and add a haze effect to create a murky appearance typical of underwater scenes. This tool is useful for photographers, videographers, or anyone looking to create artistic or realistic underwater effects in their images.

Leave a Reply

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