Please bookmark this page to avoid losing your image tool!

Photo Whimsical 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.
async function processImage(originalImg, intensity = 1.0, mood = "magical") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const w = originalImg.naturalWidth || originalImg.width;
    const h = originalImg.naturalHeight || originalImg.height;

    canvas.width = w;
    canvas.height = h;

    // Clamp intensity to a reasonable range (e.g., 0.0 to 2.0)
    // 0.0 means minimal/no effect, 1.0 is default, 2.0 is very strong.
    const clampedIntensity = Math.max(0.0, Math.min(2.0, intensity));

    // Calculate filter parameters based on intensity
    // Saturation: Normal 100%. Target for full intensity (2.0) around 180-200%.
    // Default intensity (1.0) -> 100 + (180-100)/2 * 1.0 = 140%
    const baseSaturation = 100;
    const targetMaxSaturation = 180; // Max saturation at clampedIntensity = 2.0
    const saturation = baseSaturation + (targetMaxSaturation - baseSaturation) / 2 * clampedIntensity;

    // Contrast: Normal 100%. Target for full intensity (2.0) around 130-140%.
    // Default intensity (1.0) -> 100 + (130-100)/2 * 1.0 = 115%
    const baseContrast = 100;
    const targetMaxContrast = 130;
    const contrast = baseContrast + (targetMaxContrast - baseContrast) / 2 * clampedIntensity;

    // Brightness: Normal 100%. Target for full intensity (2.0) around 110-115%.
    // Default intensity (1.0) -> 100 + (110-100)/2 * 1.0 = 105%
    const baseBrightness = 100;
    const targetMaxBrightness = 110;
    const brightness = baseBrightness + (targetMaxBrightness - baseBrightness) / 2 * clampedIntensity;

    // Blur: Max blur (e.g., 1px) at full intensity (2.0).
    // Default intensity (1.0) -> 0.8px / 2 * 1.0 = 0.4px
    const maxBlur = 0.8; // Max blur in pixels
    const blurAmount = (maxBlur / 2) * clampedIntensity;

    // Hue Rotation: Max hue rotation (e.g., 10deg) at full intensity (2.0).
    // Default intensity (1.0) -> 10 A_MAX_HUE_ROTATION / 2 * 1.0 = 5deg
    const maxHueRotation = 10; // Max hue rotation in degrees
    const hueRotation = (maxHueRotation / 2) * clampedIntensity;

    // Build the filter string for canvas context
    const filterConfig = [];
    if (Math.abs(saturation - 100) > 0.1) filterConfig.push(`saturate(${saturation.toFixed(0)}%)`);
    if (Math.abs(contrast - 100) > 0.1) filterConfig.push(`contrast(${contrast.toFixed(0)}%)`);
    if (Math.abs(brightness - 100) > 0.1) filterConfig.push(`brightness(${brightness.toFixed(0)}%)`);
    if (blurAmount > 0.05) filterConfig.push(`blur(${blurAmount.toFixed(2)}px)`); // Avoid very small blurs
    if (Math.abs(hueRotation) > 0.1) filterConfig.push(`hue-rotate(${hueRotation.toFixed(0)}deg)`);
    
    if (filterConfig.length > 0) {
        ctx.filter = filterConfig.join(' ');
    } else {
        ctx.filter = 'none';
    }
    
    ctx.drawImage(originalImg, 0, 0, w, h);

    // Clear filter before drawing overlays
    ctx.filter = 'none';

    // Vignette: Darkening at edges
    if (clampedIntensity > 0.05) { // Apply vignette even for small intensities
        const centerX = w / 2;
        const centerY = h / 2;
        const outerRadius = Math.sqrt(centerX * centerX + centerY * centerY);
        // Inner radius of vignette (clear area)
        // Becomes slightly smaller (more vignette) as intensity increases
        const innerRadiusRatioStart = 0.5; // At intensity 0
        const innerRadiusRatioEnd = 0.3;   // At intensity 2.0
        const currentInnerRatio = innerRadiusRatioStart - (innerRadiusRatioStart - innerRadiusRatioEnd) * (clampedIntensity / 2.0);
        const innerRadius = outerRadius * currentInnerRatio;


        const maxVignetteStrength = 0.6; // How dark edges become (0 to 1 alpha for black)
        const currentVignetteStrength = (maxVignetteStrength / 2) * clampedIntensity;

        const vignetteGradient = ctx.createRadialGradient(centerX, centerY, innerRadius, centerX, centerY, outerRadius);
        vignetteGradient.addColorStop(0, 'rgba(0,0,0,0)'); // Center is transparent
        vignetteGradient.addColorStop(0.8, `rgba(0,0,0,${(currentVignetteStrength * 0.5).toFixed(3)})`); // Transition
        vignetteGradient.addColorStop(1, `rgba(0,0,0,${currentVignetteStrength.toFixed(3)})`); // Edge darkness
        
        ctx.fillStyle = vignetteGradient;
        ctx.globalCompositeOperation = 'source-over'; // Default, but explicit
        ctx.fillRect(0, 0, w, h);
    }

    // Color tint overlay based on mood
    if (clampedIntensity > 0.1) {
        // Max opacity for the tint is e.g. 0.12 at intensity 2.0.
        // At default intensity 1.0, opacity is 0.06.
        const maxTintOpacity = 0.12; 
        const tintOpacity = (maxTintOpacity / 2 * clampedIntensity).toFixed(3); 

        let tintColor = '';

        switch (mood.toLowerCase()) {
            case "fairy": // Warm, slightly pinkish/golden
                tintColor = `rgba(255, 220, 230, ${tintOpacity})`; // Soft warm pink
                break;
            case "dreamy": // Soft, perhaps slightly desaturated, neutral warmth
                tintColor = `rgba(230, 225, 235, ${tintOpacity})`; // Very light, almost neutral lavender/warm gray
                break;
            case "magical": // Cool, bluish, common for "magic"
            default:
                tintColor = `rgba(200, 220, 255, ${tintOpacity})`; // Light cool blue
                break;
        }

        if (tintColor) {
            ctx.globalCompositeOperation = 'soft-light'; 
            ctx.fillStyle = tintColor; 
            ctx.fillRect(0, 0, w, h);
            ctx.globalCompositeOperation = 'source-over'; // Reset composite operation
        }
    }
    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 Whimsical Filter Application allows users to enhance their images by applying whimsical filters that modify color saturation, contrast, brightness, blur, and hue. Users can adjust the intensity of these effects, which can be particularly useful for creating magical or dreamy aesthetics in photos. This tool is ideal for photographers, social media enthusiasts, and anyone looking to add a creative touch to their images for personal projects, online sharing, or artistic expressions.

Leave a Reply

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