Please bookmark this page to avoid losing your image tool!

Image Jungle Canopy 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.
async function processImage(originalImg) {
    // Ensure the image is loaded. An Image object might be provided before its source is fully downloaded.
    if (!originalImg.complete || originalImg.naturalWidth === 0) {
        try {
            await new Promise((resolve, reject) => {
                // Add timeout to prevent indefinite hanging if image never loads or errors
                const timeoutId = setTimeout(() => reject(new Error("Image loading timed out.")), 10000); // 10s timeout
                originalImg.onload = () => {
                    clearTimeout(timeoutId);
                    resolve();
                };
                originalImg.onerror = () => {
                    clearTimeout(timeoutId);
                    reject(new Error("Image failed to load. Check the image URL or file."));
                };
                // If originalImg.src is not set, or already errored before handlers attach,
                // this might not work perfectly. This assumes src is set or will be set and is loadable.
                // The initial check for `complete` handles cases where it's already loaded/errored.
            });
        } catch (error) {
            console.error("Error during image loading:", error);
            // Create a canvas and draw an error message
            const errorCanvas = document.createElement('canvas');
            errorCanvas.width = originalImg.width || 300; // Fallback size
            errorCanvas.height = originalImg.height || 150; // Fallback size
            const errorCtx = errorCanvas.getContext('2d');
            errorCtx.fillStyle = 'rgb(240, 240, 240)';
            errorCtx.fillRect(0,0,errorCanvas.width, errorCanvas.height);
            errorCtx.fillStyle = 'red';
            errorCtx.font = '16px Arial';
            errorCtx.textAlign = 'center';
            errorCtx.fillText(error.message, errorCanvas.width / 2, errorCanvas.height / 2);
            return errorCanvas;
        }
    }

    const canvas = document.createElement('canvas');
    // Use willReadFrequently hint for potential performance improvement with getImageData/putImageData
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

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

    let imageData;
    try {
        // Get the pixel data from the canvas
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This error typically occurs due to CORS (Cross-Origin Resource Sharing) restrictions
        // if the image is loaded from a different domain without proper headers.
        console.error("Error getting image data (likely CORS issue):", e);
        // Draw an error message on the canvas indicating the problem
        ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the drawn image
        ctx.fillStyle = 'rgb(240, 240, 240)';
        ctx.fillRect(0,0,canvas.width, canvas.height);
        ctx.fillStyle = 'red';
        ctx.font = '16px Arial';
        ctx.textAlign = 'center';
        const message = 'Error: Cannot process image.';
        const subMessage = '(Possibly a CORS issue if image is from another domain)';
        ctx.fillText(message, canvas.width / 2, canvas.height / 2 - 10);
        ctx.font = '12px Arial';
        ctx.fillText(subMessage, canvas.width / 2, canvas.height / 2 + 10);
        return canvas;
    }
    
    const data = imageData.data; // This is a Uint8ClampedArray

    // Iterate over each pixel (each pixel is 4 bytes: R, G, B, A)
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];     // Red channel
        const g = data[i + 1]; // Green channel
        const b = data[i + 2]; // Blue channel
        // Alpha channel (data[i + 3]) is preserved

        // Apply Jungle Canopy Filter using specific color transformation coefficients.
        // These coefficients are chosen to:
        // 1. Strongly enhance green tones.
        // 2. Shift highlights and general tonality towards a yellowish-green,
        //    simulating sunlight filtered through leaves.
        // 3. Significantly reduce blue tones, as typically seen under dense foliage.
        // 4. Give other colors (especially reds and non-greens) a slightly darker,
        //    earthy or subdued greenish hue.
        
        const newR = r * 0.5 + g * 0.4 + b * 0.0;
        const newG = r * 0.15 + g * 1.3 + b * 0.15;
        const newB = r * 0.1 + g * 0.2 + b * 0.4;

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

    // 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 Jungle Canopy Filter Effect Tool allows users to apply a unique filter effect to images, simulating the warm, rich tones and shadows of being under a dense canopy of leaves. This tool enhances green tones, softens blues, and creates an earthy color palette, making it suitable for transforming landscape and nature photographs. Use cases include personal photo editing for social media, enhancing nature photography for prints, or creating visually appealing images for various artistic projects.

Leave a Reply

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