Please bookmark this page to avoid losing your image tool!

Melancholic Photo Filter

(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, melancholyLevel = 0.7) {
    // Sanitize and clamp melancholyLevel parameter
    let parsedLevel = parseFloat(melancholyLevel);
    if (isNaN(parsedLevel) || !isFinite(parsedLevel)) {
        // If melancholyLevel was initially undefined, it's already 0.7 from default.
        // This handles cases where it's explicitly passed as NaN, "abc", null (becomes 0 then clamped), etc.
        // If it was null, parseFloat(null) is NaN in some engines, or 0 in others.
        // To be safe, if it's not a valid finite number, revert to the default strength.
        // Strict check to ensure user intended default by not passing or passing undefined.
        if (typeof melancholyLevel === 'undefined') {
            parsedLevel = 0.7;
        } else {
             // If an invalid value was *explicitly* passed, assign default.
             // If null was passed, parseFloat(null) can be Nan or 0. If 0, level becomes 0.
             // If it's a truly invalid string like "abc", then parsedLevel is NaN.
             if(isNaN(parsedLevel) || !isFinite(parsedLevel)) parsedLevel = 0.7;
        }
    }
    const currentMelancholyLevel = Math.max(0, Math.min(1, parsedLevel));

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

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

    if (width === 0 || height === 0) {
        console.warn("Melancholic Photo Filter: Input image has zero dimensions. Returning an empty canvas.");
        canvas.width = 0;
        canvas.height = 0;
        return canvas;
    }

    canvas.width = width;
    canvas.height = height;

    ctx.drawImage(originalImg, 0, 0, width, height);

    // If melancholyLevel is effectively 0 after clamping, no pixel manipulation needed.
    if (currentMelancholyLevel === 0) {
        return canvas;
    }

    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    // Base parameters for full effect (when currentMelancholyLevel = 1)
    const targetDesaturation = 0.8;    // 0 means no desaturation, 1 means full grayscale
    const targetRedFactor = 0.85;      // Multiplier for Red channel (slight reduction/cooling)
    const targetGreenFactor = 0.95;    // Multiplier for Green channel (slight reduction/cooling)
    const targetBlueFactor = 1.15;     // Multiplier for Blue channel (slight boost/cooling)
    
    // Calculate actual effect strength based on currentMelancholyLevel
    // Lerp (Linear Interpolation): newValue = startValue + (endValue - startValue) * t
    // For desaturation, start is 0 (no desaturation), end is targetDesaturation. t is currentMelancholyLevel.
    const actualDesaturation = targetDesaturation * currentMelancholyLevel;
    
    // For color factors, start is 1.0 (no change), end is targetFactor. t is currentMelancholyLevel.
    const actualRedFactor = 1.0 + (targetRedFactor - 1.0) * currentMelancholyLevel;
    const actualGreenFactor = 1.0 + (targetGreenFactor - 1.0) * currentMelancholyLevel;
    const actualBlueFactor = 1.0 + (targetBlueFactor - 1.0) * currentMelancholyLevel;

    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.

        // 1. Desaturation
        if (actualDesaturation > 0) { // Avoid calculation if no desaturation
            const luma = 0.299 * r + 0.587 * g + 0.114 * b; // Calculate luminance
            r = r * (1 - actualDesaturation) + luma * actualDesaturation;
            g = g * (1 - actualDesaturation) + luma * actualDesaturation;
            b = b * (1 - actualDesaturation) + luma * actualDesaturation;
        }

        // 2. Apply cool tint and subtle brightness adjustment via channel multiplication
        r *= actualRedFactor;
        g *= actualGreenFactor;
        b *= actualBlueFactor;

        // Clamp values to ensure they are within the [0, 255] range
        data[i] = Math.max(0, Math.min(255, r));
        data[i + 1] = Math.max(0, Math.min(255, g));
        data[i + 2] = Math.max(0, Math.min(255, b));
    }

    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 Melancholic Photo Filter is a tool designed to apply a unique aesthetic to your images, transforming their appearance to evoke a sense of melancholy. By adjusting the ‘melancholy level’, users can control the intensity of the effect, which includes desaturating colors and modifying the color tones to create a cooler, more subdued palette. This tool is useful for artists, photographers, or anyone looking to artistically alter images for social media posts, personal projects, or creative presentations, adding a distinctive emotional touch to their visuals.

Leave a Reply

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