Please bookmark this page to avoid losing your image tool!

Image Old Effects Filter Applier

(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, sepiaAmount = 80, noiseAmount = 30, vignetteAmount = 60, scratchAmount = 25) {
    // Ensure parameters are numbers
    const sepia = Number(sepiaAmount) || 0;
    const noise = Number(noiseAmount) || 0;
    const vignette = Number(vignetteAmount) || 0;
    const scratches = Number(scratchAmount) || 0;

    // Create the main canvas and get its context
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    // Set dimensions based on the natural dimensions of the image
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalWidth ? originalImg.naturalHeight : originalImg.height;
    canvas.width = width;
    canvas.height = height;

    // Step 1: Draw the base image with color adjustments
    // Old photos usually have lower contrast, slightly reduced brightness, less overall saturation, and a sepia tone.
    ctx.filter = `sepia(${sepia}%) contrast(85%) brightness(95%) grayscale(15%)`;
    ctx.drawImage(originalImg, 0, 0, width, height);
    ctx.filter = 'none'; // reset filter for subsequent layers

    // Step 2: Apply Film Grain / Noise
    if (noise > 0) {
        // Create an off-screen canvas for the noise pattern
        const noiseCanvas = document.createElement('canvas');
        const noiseCtx = noiseCanvas.getContext('2d');
        noiseCanvas.width = 150;
        noiseCanvas.height = 150;

        const imgData = noiseCtx.createImageData(noiseCanvas.width, noiseCanvas.height);
        const data = imgData.data;
        
        // Max alpha for noise is set relatively low to blend nicely
        const maxAlpha = (noise / 100) * 80; 

        for (let i = 0; i < data.length; i += 4) {
            const val = Math.random() * 255; // Monochromatic noise
            data[i] = val;     // R
            data[i + 1] = val; // G
            data[i + 2] = val; // B
            data[i + 3] = maxAlpha; // Alpha
        }
        noiseCtx.putImageData(imgData, 0, 0);

        // Overlay the noise onto the main canvas
        ctx.globalCompositeOperation = 'overlay';
        ctx.fillStyle = ctx.createPattern(noiseCanvas, 'repeat');
        ctx.fillRect(0, 0, width, height);
        ctx.globalCompositeOperation = 'source-over'; // Reset
    }

    // Step 3: Apply vintage scratches and dust
    if (scratches > 0) {
        const scratchCount = (width * height / 50000) * (scratches / 100);
        
        // Add white/light scratches
        ctx.globalCompositeOperation = 'screen';
        for (let i = 0; i < scratchCount; i++) {
            ctx.beginPath();
            const x = Math.random() * width;
            const y = Math.random() * height;
            const length = Math.random() * 150 + 20;
            // Orient scratches mostly vertically, fitting old film feeding mechanisms
            const angle = Math.PI / 2 + (Math.random() * 0.2 - 0.1);
            
            ctx.moveTo(x, y);
            ctx.lineTo(x + Math.cos(angle) * length, y + Math.sin(angle) * length);
            ctx.lineWidth = Math.random() * 1 + 0.5;
            ctx.strokeStyle = `rgba(255, 255, 255, ${Math.random() * 0.4 * (scratches / 100)})`;
            ctx.stroke();
        }

        // Add dark scratches and artifact speckles
        ctx.globalCompositeOperation = 'multiply';
        for (let i = 0; i < scratchCount / 2; i++) {
            ctx.beginPath();
            const x = Math.random() * width;
            const y = Math.random() * height;
            const length = Math.random() * 60 + 10;
            const angle = Math.PI / 2 + (Math.random() * 0.6 - 0.3);
            
            ctx.moveTo(x, y);
            ctx.lineTo(x + Math.cos(angle) * length, y + Math.sin(angle) * length);
            ctx.lineWidth = Math.random() * 1.5 + 0.5;
            ctx.strokeStyle = `rgba(50, 40, 30, ${Math.random() * 0.5 * (scratches / 100)})`;
            ctx.stroke();
        }
        ctx.globalCompositeOperation = 'source-over'; // Reset
    }

    // Step 4: Apply Vignette Matrix (darkened edges common in vintage camera lenses)
    if (vignette > 0) {
        const cx = width / 2;
        const cy = height / 2;
        // The gradient radius needs to cover up to the corners
        const maxRadius = Math.sqrt(cx * cx + cy * cy); 
        
        const radGrad = ctx.createRadialGradient(cx, cy, maxRadius * 0.4, cx, cy, maxRadius);
        radGrad.addColorStop(0, 'rgba(0,0,0,0)');
        radGrad.addColorStop(0.7, `rgba(0,0,0, ${vignette / 100 * 0.4})`);
        radGrad.addColorStop(1, `rgba(0,0,0, ${vignette / 100 * 0.9})`);
        
        ctx.globalCompositeOperation = 'multiply';
        ctx.fillStyle = radGrad;
        ctx.fillRect(0, 0, width, height);
        ctx.globalCompositeOperation = 'source-over'; // Reset
    }
    
    // Step 5: Simple Light Leak (often happens when old film is exposed to light)
    if (vignette > 0 || sepia > 0) {
        ctx.globalCompositeOperation = 'screen';
        const leakGrad = ctx.createLinearGradient(0, 0, width * 0.25, height * 0.1);
        leakGrad.addColorStop(0, `rgba(255, 120, 40, 0.15)`);
        leakGrad.addColorStop(1, 'rgba(255, 120, 40, 0)');
        ctx.fillStyle = leakGrad;
        ctx.fillRect(0, 0, width * 0.3, height * 0.2);
        ctx.globalCompositeOperation = 'source-over';
    }

    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 Image Old Effects Filter Applier is a tool designed to give modern digital photos a vintage, nostalgic appearance. It applies several classic film aesthetics, including sepia tones, film grain/noise, realistic scratches and dust artifacts, darkened vignette edges, and subtle light leaks. This tool is ideal for photographers, social media creators, or designers looking to add a retro or historical feel to their images for artistic projects, themed content, or storytelling.

Leave a Reply

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