Please bookmark this page to avoid losing your image tool!

Photo Sentimental 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, intensity = 0.8, desaturation = 0.4, sepiaTone = 0.5, warmth = 0.15, vignetteStrength = 0.6, vignetteSoftness = 0.5) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Ensure the image is loaded and has dimensions
    if (!originalImg || originalImg.width === 0 || originalImg.height === 0 || !originalImg.complete) {
        console.error("Image not loaded or invalid.");
        // Return a blank or minimal canvas if image is problematic
        canvas.width = originalImg.width || 1;
        canvas.height = originalImg.height || 1;
        // Optionally draw a placeholder or clear it
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        return canvas;
    }

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

    ctx.drawImage(originalImg, 0, 0);

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

    const centerX = width / 2;
    const centerY = height / 2;
    const maxImageRadius = Math.sqrt(centerX * centerX + centerY * centerY);

    // Normalize parameters to be within [0, 1] if they are not, can be done here or assumed valid
    intensity = Math.max(0, Math.min(1, intensity));
    desaturation = Math.max(0, Math.min(1, desaturation));
    sepiaTone = Math.max(0, Math.min(1, sepiaTone));
    warmth = Math.max(0, Math.min(1, warmth));
    vignetteStrength = Math.max(0, Math.min(1, vignetteStrength));
    vignetteSoftness = Math.max(0, Math.min(1, vignetteSoftness));

    for (let i = 0; i < data.length; i += 4) {
        const originalR = data[i];
        const originalG = data[i + 1];
        const originalB = data[i + 2];

        let r = originalR;
        let g = originalG;
        let b = originalB;

        // 1. Desaturation
        if (desaturation > 0) {
            const gray = 0.299 * r + 0.587 * g + 0.114 * b;
            r = r * (1 - desaturation) + gray * desaturation;
            g = g * (1 - desaturation) + gray * desaturation;
            b = b * (1 - desaturation) + gray * desaturation;
        }

        // Clamp after this stage before next calculations if values could go out of typical 0-255 range
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));

        // 2. Sepia Tone
        if (sepiaTone > 0) {
            const sr = (r * 0.393) + (g * 0.769) + (b * 0.189);
            const sg = (r * 0.349) + (g * 0.686) + (b * 0.168);
            const sb = (r * 0.272) + (g * 0.534) + (b * 0.131);
            
            r = r * (1 - sepiaTone) + sr * sepiaTone;
            g = g * (1 - sepiaTone) + sg * sepiaTone;
            b = b * (1 - sepiaTone) + sb * sepiaTone;
        }
        
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));

        // 3. Warmth
        if (warmth > 0) {
            r += 50 * warmth; // Add warmth to red
            g += 25 * warmth; // Add less warmth to green
            // b -= 10 * warmth; // Optionally cool down blue to enhance orange/yellow feel
        }

        // Clamp color-filtered values before vignette
        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
        let vignetteMultiplier = 1.0;
        if (vignetteStrength > 0 && maxImageRadius > 0) {
            const x = (i / 4) % width;
            const y = Math.floor((i / 4) / width);
            const dx = x - centerX;
            const dy = y - centerY;
            const dist = Math.sqrt(dx * dx + dy * dy);
            
            const relativeDist = dist / maxImageRadius; // 0 at center, 1 at corners
            // vignetteSoftness (0-1): 0 = sharp (high power), 1 = soft (low power)
            // Power ranges from 1 (soft, linear falloff) to 4 (sharper, cubic-like falloff)
            const vignettePower = 1 + (1 - vignetteSoftness) * 3; 
            
            const calculatedVignetteEffect = Math.pow(relativeDist, vignettePower) * vignetteStrength;
            vignetteMultiplier = Math.max(0, 1.0 - calculatedVignetteEffect);
        }

        r *= vignetteMultiplier;
        g *= vignetteMultiplier;
        b *= vignetteMultiplier;

        // Clamp after vignette (multiplication might slightly push out of bounds if vignetteMultiplier > 1, not in this case)
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));

        // 5. Overall Intensity: Blend the fully filtered pixel (r,g,b) with the original pixel
        data[i]    = originalR * (1 - intensity) + r * intensity;
        data[i+1]  = originalG * (1 - intensity) + g * intensity;
        data[i+2]  = originalB * (1 - intensity) + b * intensity;
        // Alpha (data[i+3]) is preserved from the original image
    }

    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 Sentimental Filter is an online tool designed to enhance images with a range of artistic effects that evoke feelings and moods. Users can adjust parameters such as intensity, desaturation, sepia tone, warmth, and vignette strength to create personalized visual effects. This tool can be ideal for photographers wanting to add emotional depth to their photos, social media users looking to enhance their images for better engagement, or anyone interested in transforming their pictures into unique presentations with a nostalgic or warm atmosphere.

Leave a Reply

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