Please bookmark this page to avoid losing your image tool!

Elegant Photo Filter 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, filterType = 'sepia', intensity = 0.7) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height if available for intrinsic dimensions, fallback to width/height.
    // Assumes the image is loaded; caller should handle img.onload.
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    // If canvas dimensions are zero (e.g., image not loaded or invalid), return an empty canvas.
    if (canvas.width === 0 || canvas.height === 0) {
        console.warn("Image has zero dimensions. Ensure it's loaded before processing.");
        return canvas;
    }
    
    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    // Clamp intensity to the valid range [0.0, 1.0]
    const currentIntensity = Math.max(0.0, Math.min(1.0, intensity));

    // If intensity is 0, no filtering is needed. Return canvas with the original image.
    if (currentIntensity === 0) {
        return canvas;
    }

    let imageData;
    try {
        // Get the image data from the canvas.
        // This can throw a security error if the image is cross-origin and the canvas becomes tainted.
        // The image must be same-origin or have CORS headers permitting use in a canvas.
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        console.error("Error getting image data: ", e.message, "Ensure image is same-origin or CORS-enabled.");
        // Return the canvas with the original image drawn, as filtering isn't possible.
        return canvas;
    }
    
    const data = imageData.data;

    // Determine the actual filter type to apply.
    // Convert to lowercase and fallback to 'sepia' if filterType is not a string or is invalid.
    let actualFilterType = (typeof filterType === 'string') ? filterType.toLowerCase() : 'sepia';
    const validFilters = ['sepia', 'grayscale', 'cool_monochrome', 'warm_vintage'];
    if (!validFilters.includes(actualFilterType)) {
        actualFilterType = 'sepia'; // Default to 'sepia' for unrecognized filter strings
    }

    // Loop through each pixel (R, G, B, A components)
    for (let i = 0; i < data.length; i += 4) {
        const r_orig = data[i];
        const g_orig = data[i + 1];
        const b_orig = data[i + 2];
        // Alpha channel (data[i+3]) is not modified in these filters.

        let r_filt = r_orig;
        let g_filt = g_orig;
        let b_filt = b_orig;

        // Apply the selected filter logic
        switch (actualFilterType) {
            case 'sepia':
                r_filt = (r_orig * 0.393) + (g_orig * 0.769) + (b_orig * 0.189);
                g_filt = (r_orig * 0.349) + (g_orig * 0.686) + (b_orig * 0.168);
                b_filt = (r_orig * 0.272) + (g_orig * 0.534) + (b_orig * 0.131);
                break;
            case 'grayscale':
                // Using luminosity method for grayscale conversion
                const gray = (r_orig * 0.299) + (g_orig * 0.587) + (b_orig * 0.114);
                r_filt = gray;
                g_filt = gray;
                b_filt = gray;
                break;
            case 'cool_monochrome':
                const gray_cool = (r_orig * 0.299) + (g_orig * 0.587) + (b_orig * 0.114);
                r_filt = gray_cool * 0.95; // Desaturate red slightly for coolness
                g_filt = gray_cool * 1.02; // Slight boost to green (towards cyan)
                b_filt = gray_cool * 1.10; // Boost blue
                break;
            case 'warm_vintage':
                const desaturationFactor = 0.4; // How much to desaturate
                const gray_warm = (r_orig * 0.299) + (g_orig * 0.587) + (b_orig * 0.114);
                
                // Desaturated intermediate colors
                const inter_r = r_orig * (1 - desaturationFactor) + gray_warm * desaturationFactor;
                const inter_g = g_orig * (1 - desaturationFactor) + gray_warm * desaturationFactor;
                const inter_b = b_orig * (1 - desaturationFactor) + gray_warm * desaturationFactor;

                // Apply warm tint
                r_filt = inter_r * 1.15; // Boost red
                g_filt = inter_g * 1.05; // Slight boost to green
                b_filt = inter_b * 0.90; // Reduce blue
                break;
        }

        // Clamp filtered color components to the [0, 255] range
        r_filt = Math.max(0, Math.min(255, r_filt));
        g_filt = Math.max(0, Math.min(255, g_filt));
        b_filt = Math.max(0, Math.min(255, b_filt));
        
        // Apply intensity: linear interpolation between original and filtered color
        // C_final = (1 - intensity) * C_original + intensity * C_filtered
        // Math.round is used to ensure integer pixel values.
        data[i]   = Math.round((1 - currentIntensity) * r_orig + currentIntensity * r_filt);
        data[i+1] = Math.round((1 - currentIntensity) * g_orig + currentIntensity * g_filt);
        data[i+2] = Math.round((1 - currentIntensity) * b_orig + currentIntensity * b_filt);
        // Final values are implicitly clamped as they are interpolations of clamped values.
    }

    // 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 Elegant Photo Filter Tool allows users to apply various artistic filters to their images, enhancing their visual appeal. Users can choose from filters such as sepia, grayscale, cool monochrome, and warm vintage, and adjust the intensity of the effect. This tool is ideal for photographers, social media enthusiasts, or anyone looking to personalize their images for presentations, online sharing, or creative projects.

Leave a Reply

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