Please bookmark this page to avoid losing your image tool!

Image Deep Sea Filter Effect 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, depth = 0.7) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const imgWidth = originalImg.naturalWidth;
    const imgHeight = originalImg.naturalHeight;

    // Handle cases where the image might not be loaded or has no dimensions
    if (imgWidth === 0 || imgHeight === 0) {
        canvas.width = 0;
        canvas.height = 0;
        return canvas; // Return an empty 0x0 canvas
    }

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

    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    // Convert depth parameter to a number.
    // Handles cases:
    // - number (e.g., 0.5) -> 0.5
    // - string parsable as number (e.g., "0.5") -> 0.5
    // - null -> 0
    // - undefined -> uses default 0.7 (handled by parameter default)
    // - string not parsable as number (e.g., "foo") -> NaN
    // - NaN -> NaN
    const numDepth = Number(depth);

    // Clamp the depth value to the range [0.0, 1.0].
    // If numDepth is NaN, clampedDepth will also be NaN.
    const clampedDepth = Math.max(0.0, Math.min(1.0, numDepth));

    // If clampedDepth is NaN (due to invalid string input like "foo"),
    // all subsequent calculations involving it will result in NaN.
    // When NaN is assigned to a Uint8ClampedArray element, it becomes 0.
    // So, an invalid depth string will result in a black image.
    // If depth was `null`, clampedDepth is 0 (original image, no filter).

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        // This can happen if the canvas is tainted (e.g., cross-origin image without CORS)
        console.error("Error getting ImageData for Deep Sea Filter:", e);
        // Return the canvas with the original image drawn, as we can't process pixels
        return canvas;
    }
    
    const data = imageData.data; // Uint8ClampedArray: [R, G, B, A, R, G, B, A, ...]

    // Define the target "deep sea" color towards which pixels will be tinted
    const targetR = 10;  // Dark, slightly desaturated blue/cyan
    const targetG = 40;
    const targetB = 90;

    // Define how much overall brightness is reduced at maximum depth (clampedDepth = 1.0)
    // E.g., 0.5 means brightness can be reduced by up to 50%.
    const maxBrightnessReduction = 0.5;
    const overallBrightnessFactor = 1.0 - (clampedDepth * maxBrightnessReduction);

    // Define how much specific color channels are attenuated at maximum depth,
    // simulating light absorption in water (reds disappear first, then greens).
    const redLightAbsorption = clampedDepth * 0.6;   // Max 60% further reduction for red
    const greenLightAbsorption = clampedDepth * 0.3; // Max 30% further reduction for green

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        // Alpha channel (data[i+3]) is preserved

        // 1. Tinting: Interpolate original pixel color towards the target deep sea color.
        // The influence of the target color increases with depth.
        let newR = r * (1 - clampedDepth) + targetR * clampedDepth;
        let newG = g * (1 - clampedDepth) + targetG * clampedDepth;
        let newB = b * (1 - clampedDepth) + targetB * clampedDepth;

        // 2. Apply overall brightness reduction.
        // This simulates the general darkness of deeper water.
        newR *= overallBrightnessFactor;
        newG *= overallBrightnessFactor;
        newB *= overallBrightnessFactor;

        // 3. Apply selective light absorption for different colors.
        // Red light is absorbed more strongly than green, and green more than blue.
        newR *= (1 - redLightAbsorption);
        newG *= (1 - greenLightAbsorption);
        // Blue light is generally the last to be absorbed, so it's not further attenuated here.
        // Its prominence comes from the tint and other colors' reduction.

        // Assign new values. Uint8ClampedArray automatically clamps values
        // to the 0-255 range and converts NaN to 0.
        data[i] = newR;
        data[i + 1] = newG;
        data[i + 2] = newB;
    }

    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 Deep Sea Filter Effect Application allows users to apply a unique deep sea color filter to images, simulating the visual effects of underwater environments. By adjusting the depth parameter, users can customize the strength of the effect, altering the image to feature darker tones with a bluish tint while reducing the visibility of red and green colors, akin to the effect of water absorption. This tool is useful for artists, photographers, or anyone looking to create atmospheric images reminiscent of underwater scenes.

Leave a Reply

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