Please bookmark this page to avoid losing your image tool!

Melodramatic 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) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth/Height for true image dimensions. Fallback to width/height.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    // Handle cases where image dimensions are not available (e.g., image not yet loaded or invalid)
    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Melodramatic Photo Filter: Image not loaded or has zero dimensions.");
        // Return a small, empty canvas as a fallback.
        canvas.width = 1;
        canvas.height = 1;
        return canvas;
    }
    
    canvas.width = imgWidth;
    canvas.height = imgHeight;

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

    // Get the pixel data from the canvas
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data; // Uint8ClampedArray: [R,G,B,A, R,G,B,A, ...]

    const width = canvas.width;
    const height = canvas.height;
    const centerX = width / 2;
    const centerY = height / 2;
    // Calculate the maximum distance from the center to a corner, for vignette normalization
    const maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);

    // --- Melodramatic Filter Parameters ---
    // These values are chosen to create a "melodramatic" look.
    const desaturationFactor = 0.6; // Range 0-1. 0 = original colors, 1 = full grayscale. (0.6 means 60% towards grayscale)
    const contrastFactor = 1.4;     // Values > 1 increase contrast. (1.4 means 40% more contrast)
    const redReductionFactor = 0.95; // Slightly reduce red channel (e.g., 0.95 for 5% reduction)
    const blueBoostFactor = 1.10;    // Slightly boost blue channel (e.g., 1.10 for 10% boost)
    const vignetteStrength = 0.8;   // Strength of vignette. Range 0-1. (0.8 is a fairly strong darkening at edges)
    const vignetteFalloff = 1.5;    // Controls sharpness of vignette fade. (1=linear, 2=quadratic-like, 1.5 is in between)

    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];

        // 1. Desaturation
        // Calculate luminance (perceived brightness/grayscale value)
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        // Interpolate between the original color and its grayscale equivalent
        r = r * (1 - desaturationFactor) + gray * desaturationFactor;
        g = g * (1 - desaturationFactor) + gray * desaturationFactor;
        b = b * (1 - desaturationFactor) + gray * desaturationFactor;

        // 2. Contrast Adjustment
        // Stretch color values away from the midpoint (128)
        r = contrastFactor * (r - 128) + 128;
        g = contrastFactor * (g - 128) + 128;
        b = contrastFactor * (b - 128) + 128;

        // 3. Cool Tint Application
        // Apply multiplicative factors to red and blue channels for a cooler tone
        r *= redReductionFactor;
        b *= blueBoostFactor;

        // Clamp R, G, B values to the valid [0, 255] range after color adjustments.
        // This is important before applying the vignette, which is a multiplicative effect.
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));

        // 4. Vignette Effect
        // Calculate current pixel's (x, y) coordinates
        const pixelIndex = i / 4;
        const currentX = pixelIndex % width;
        const currentY = Math.floor(pixelIndex / width);
        
        // Calculate distance of the current pixel from the center
        const dx = currentX - centerX;
        const dy = currentY - centerY;
        const distanceToCenter = Math.sqrt(dx * dx + dy * dy);
        
        // Normalize the distance (0 at center, 1 at corners/edges defined by maxDistance)
        const normalizedDist = (maxDistance > 0) ? (distanceToCenter / maxDistance) : 0; // Avoid division by zero for tiny images
        
        // Calculate vignette multiplier. It's 1 at the center, decreasing towards edges.
        // The `vignetteFalloff` power controls the curve of the fade.
        const vignetteEffectAmount = vignetteStrength * Math.pow(normalizedDist, vignetteFalloff);
        const vignetteMultiplier = Math.max(0, 1.0 - vignetteEffectAmount); // Ensure multiplier is not negative
        
        // Apply vignette by multiplying color values
        r *= vignetteMultiplier;
        g *= vignetteMultiplier;
        b *= vignetteMultiplier;

        // Final assignment to image data.
        // Uint8ClampedArray automatically clamps values to [0, 255] and rounds them.
        data[i] = r;
        data[i + 1] = g;
        data[i + 2] = b;
        // Alpha channel (data[i + 3]) is preserved.
    }

    // Write the modified pixel data back to 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 Melodramatic Photo Filter is an online tool that applies a distinctive visual style to images by enhancing contrast, desaturating colors, and adding a vignette effect. This tool is ideal for users looking to create dramatic, artistic photography effects, making it suitable for social media posts, personal projects, or any creative endeavor where a stylized look is desired. By transforming regular photos into visually striking images, it caters to photographers, graphic designers, and anyone interested in enhancing their visual content.

Leave a Reply

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