Please bookmark this page to avoid losing your image tool!

Image Ocean Depth 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.
function processImage(originalImg, depthLevel = 0.5) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height for intrinsic dimensions, fallback to width/height
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    // If image dimensions are zero, it might not be loaded or is invalid.
    // To prevent errors, ensure canvas has at least 1x1 dimensions.
    if (imgWidth === 0 || imgHeight === 0) {
        console.warn("Original image has zero dimensions. Outputting 1x1 canvas.");
        canvas.width = 1;
        canvas.height = 1;
        // Optionally, fill with a default color or leave transparent
        ctx.fillStyle = 'rgba(0,0,0,0)';
        ctx.fillRect(0,0,1,1);
        return canvas;
    }

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

    try {
        ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Error drawing image to canvas: ", e);
        // Return the empty canvas or throw an error if drawing fails
        return canvas;
    }
    
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        console.error("Could not getImageData (e.g., tainted canvas from_ cross-origin image): ", e);
        // If getImageData fails, we can't process pixels.
        // Return the canvas with the original image drawn (if drawImage succeeded).
        return canvas;
    }
    
    const data = imageData.data;

    // Validate and process depthLevel parameter
    // It should be a number or a string coercible to a number.
    let dLevelNum = Number(depthLevel);

    // If depthLevel is not a valid number (e.g., "foo", null, undefined after Number())
    // Note: `depthLevel = 0.5` in function signature handles undefined.
    // This explicit check handles NaN from `Number("text")` or if `null` was passed.
    if (isNaN(dLevelNum) || dLevelNum === null) { 
        if (typeof depthLevel !== 'undefined' && depthLevel !== null) { // Avoid warning for default case
             console.warn(`Invalid depthLevel parameter: "${depthLevel}". Using default 0.5.`);
        }
        dLevelNum = 0.5; // Default value
    }
    
    // Clamp depthLevel to the range [0, 1]
    const dLevel = Math.max(0, Math.min(1, dLevelNum));

    // Effect parameters dynamically calculated based on the validated depthLevel
    const redAbsorptionEffect = dLevel * 0.75;   // How much red light is absorbed (max 75%)
    const greenAbsorptionEffect = dLevel * 0.5; // How much green light is absorbed (max 50%)
    const blueAbsorptionEffect = dLevel * 0.25;  // How much blue light is absorbed (max 25%)

    // Overall light reduction factor due to water absorbing light
    const overallLightReduction = 1.0 - dLevel * 0.4; // Max 40% darker

    // Define the ambient "water color" (a medium-deep blue)
    // This is the color light tends towards as it passes through more water.
    const waterColorR = 10;
    const waterColorG = 60;
    const waterColorB = 110;
    
    // How much the pixel color should shift towards the waterColor.
    // Increases with depth. Max 45% blend towards waterColor.
    const colorBlendIntensity = dLevel * 0.45; 

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

        // 1. Simulate light absorption by water: attenuate color channels
        let processedR = r * (1 - redAbsorptionEffect);
        let processedG = g * (1 - greenAbsorptionEffect);
        let processedB = b * (1 - blueAbsorptionEffect);
        
        // 2. Simulate overall darkening due to depth
        processedR *= overallLightReduction;
        processedG *= overallLightReduction;
        processedB *= overallLightReduction;

        // 3. Blend with the ambient water color (Linear Interpolation)
        // pix_final = (1 - k) * pix_current + k * water_color
        processedR = (1 - colorBlendIntensity) * processedR + colorBlendIntensity * waterColorR;
        processedG = (1 - colorBlendIntensity) * processedG + colorBlendIntensity * waterColorG;
        processedB = (1 - colorBlendIntensity) * processedB + colorBlendIntensity * waterColorB;

        // Ensure values are integers and clamped to the valid [0, 255] range
        data[i] = Math.max(0, Math.min(255, Math.round(processedR)));
        data[i+1] = Math.max(0, Math.min(255, Math.round(processedG)));
        data[i+2] = Math.max(0, Math.min(255, Math.round(processedB)));
    }

    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 Ocean Depth Filter Effect Tool allows users to apply a unique underwater effect to images, simulating the visual characteristics of light as it penetrates water at different depths. By adjusting the depth level, users can achieve various levels of color absorption and darkening, effectively mimicking the natural hues of aquatic environments. This tool can be valuable for artists, designers, and anyone looking to enhance photographs with underwater aesthetics, such as creating promotional material for ocean-related events, enhancing vacation photos, or developing immersive visual content for digital projects.

Leave a Reply

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