Please bookmark this page to avoid losing your image tool!

Photo Cool 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, overlayColor = "#0077AA", overlayOpacity = 0.25, contrastFactor = 1.15, brightnessOffset = 5, desaturation = 0.15) {
    
    // Helper to parse hex color string to [R, G, B] array
    // This helper is defined inside processImage to keep it self-contained.
    function parseHexColor(hex) {
        // Ensure hex is a string, trim whitespace, remove leading #
        hex = String(hex).trim().replace(/^#/, '');
        
        if (hex.length === 3) {
            hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
        }
        
        // Ensure it's a 6-digit hex string containing valid characters
        if (!/^[0-9A-Fa-f]{6}$/.test(hex)) {
            console.warn(`Invalid hex color: "#${hex}". Using default black ([0,0,0]).`);
            return [0, 0, 0]; // Default to black if invalid format
        }

        const bigint = parseInt(hex, 16);
        const r = (bigint >> 16) & 255;
        const g = (bigint >> 8) & 255;
        const b = bigint & 255;
        return [r, g, b];
    }

    const [tintR, tintG, tintB] = parseHexColor(overlayColor);

    const canvas = document.createElement('canvas');
    // Optimization hint for frequent readback operations
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); 

    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

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

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

    // If image dimensions are invalid, return the canvas (possibly empty or 0x0)
    if (imgWidth === 0 || imgHeight === 0) {
        console.warn("Image has zero width or height.");
        return canvas; 
    }
    
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        // This can happen due to tainted canvas (CORS issues) or other errors
        console.error("Failed to get image data: ", e);
        // Draw an error message on the canvas as feedback
        ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the drawn image
        ctx.fillStyle = "rgba(200, 0, 0, 0.7)"; // Semi-transparent red background
        ctx.fillRect(0, 0, canvas.width, canvas.height); 
        ctx.fillStyle = "white";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        
        // Adjust font size based on canvas size for better readability
        const fontSize = Math.min(24, Math.max(12, canvas.width / 20));
        ctx.font = `${fontSize}px Arial`;
        
        ctx.fillText("Error: Could not process image.", canvas.width / 2, canvas.height / 2 - fontSize * 0.6);
        ctx.font = `${fontSize * 0.75}px Arial`;
        ctx.fillText(e.message.length > 50 ? e.message.substring(0,47) + "..." : e.message, canvas.width / 2, canvas.height / 2 + fontSize * 0.6);
        return canvas;
    }
    
    const data = imageData.data;

    // Clamp parameter values to sensible ranges
    const currentDesaturation = Math.max(0, Math.min(1, desaturation));
    const currentOverlayOpacity = Math.max(0, Math.min(1, overlayOpacity));
    // Allow contrast factor to be 0 (results in grey image), but not negative.
    const currentContrastFactor = Math.max(0, contrastFactor); 
    // brightnessOffset can be negative or positive, no specific clamping beyond data type limits

    // Iterate over each pixel
    // data is a flat array: [R, G, B, A, R, G, B, A, ...]
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];
        // Alpha channel (data[i+3]) is preserved by default

        // 1. Apply Desaturation (0.0 to 1.0)
        if (currentDesaturation > 0) {
            const luma = 0.299 * r + 0.587 * g + 0.114 * b; // Standard luma calculation
            r = r * (1 - currentDesaturation) + luma * currentDesaturation;
            g = g * (1 - currentDesaturation) + luma * currentDesaturation;
            b = b * (1 - currentDesaturation) + luma * currentDesaturation;
        }

        // 2. Apply Brightness (-255 to 255 relative to current values)
        if (brightnessOffset !== 0) {
            r += brightnessOffset;
            g += brightnessOffset;
            b += brightnessOffset;
        }

        // 3. Apply Contrast (0.0 to Infinity, 1.0 is no change)
        if (currentContrastFactor !== 1.0) {
            // Pixel values are adjusted relative to the midpoint (128)
            r = (r - 128) * currentContrastFactor + 128;
            g = (g - 128) * currentContrastFactor + 128;
            b = (b - 128) * currentContrastFactor + 128;
        }
        
        // 4. Apply Tint Overlay (opacity 0.0 to 1.0)
        if (currentOverlayOpacity > 0) {
            r = r * (1 - currentOverlayOpacity) + tintR * currentOverlayOpacity;
            g = g * (1 - currentOverlayOpacity) + tintG * currentOverlayOpacity;
            b = b * (1 - currentOverlayOpacity) + tintB * currentOverlayOpacity;
        }

        // Clamp final R, G, B values to the 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)));
        // data[i+3] (alpha) remains unchanged
    }

    // Put the modified image 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 Photo Cool Filter Application is a versatile online tool designed to enhance images by applying various visual effects. Users can adjust parameters such as brightness, contrast, and saturation, as well as apply a color overlay to create unique looks. This tool is ideal for photographers, graphic designers, or anyone looking to stylize their images for social media, presentations, or personal projects. With its user-friendly interface, users can easily preview changes in real-time, making it a great option for both casual and professional use.

Leave a Reply

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