Please bookmark this page to avoid losing your image tool!

Image 90s Retro 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, grainStrength = 30, coolTintStrength = 0.3, vignetteAmount = 0.5, contrastValue = 1.1, brightnessValue = 5) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Ensure originalImg is loaded, otherwise width/height might be 0
    // For an Image object from `new Image()`, width/height are set after `onload`.
    // For an <img> DOM element, naturalWidth/naturalHeight are intrinsic dimensions.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    canvas.width = imgWidth;
    canvas.height = imgHeight;

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

    if (imgWidth === 0 || imgHeight === 0) {
        // Avoid processing if image is not loaded or has no dimensions
        return canvas;
    }
    
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    // Max distance from center to a corner, used for normalizing vignette distance
    const maxDistHypot = Math.sqrt(centerX * centerX + centerY * centerY); 

    function clamp(value, min, max) {
        return Math.max(min, Math.min(value, max));
    }

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

        // Order of operations:
        // 1. Contrast
        // 2. Brightness
        // 3. Color Tinting
        // 4. Grain
        // 5. Vignette
        // 6. Final Clamp

        // 1. Apply Contrast
        // Adjusts the difference between light and dark areas.
        // Values are shifted relative to the midpoint (128).
        if (contrastValue !== 1) {
            r = (r - 128) * contrastValue + 128;
            g = (g - 128) * contrastValue + 128;
            b = (b - 128) * contrastValue + 128;
        }

        // 2. Apply Brightness
        // Adds a flat amount to each channel.
        if (brightnessValue !== 0) {
            r += brightnessValue;
            g += brightnessValue;
            b += brightnessValue;
        }
        
        // 3. Apply 90s Cool Tint
        // Reduces reds and greens, boosts blues for a characteristic "cool" retro feel.
        if (coolTintStrength > 0) {
            let r_tinted = r * (1 - 0.15 * coolTintStrength); // Reduce red saturation/value
            let g_tinted = g * (1 - 0.10 * coolTintStrength); // Slightly reduce green
            // Boost blue: part multiplicative (scales with existing blue), part additive (lifts shadows)
            let b_tinted = b * (1 + 0.20 * coolTintStrength) + (15 * coolTintStrength); 
            
            r = r_tinted;
            g = g_tinted;
            b = b_tinted;
        }

        // 4. Add Grain
        // Simulates film grain by adding random noise.
        if (grainStrength > 0) {
            // Generate noise between -grainStrength/2 and +grainStrength/2
            const noise = (Math.random() - 0.5) * grainStrength; 
            r += noise;
            g += noise;
            b += noise;
        }
        
        // 5. Apply Vignette
        // Darkens the edges of the image.
        if (vignetteAmount > 0 && maxDistHypot > 0) { // maxDistHypot check for 1x1 pixel images
            const x = (i / 4) % canvas.width;
            const y = Math.floor((i / 4) / canvas.width);
            
            const distCurrent = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
            
            // vignettePower controls the falloff curve. Higher values mean a sharper/faster falloff.
            const vignettePower = 2.0; 
            // Calculate vignette factor: 1 at center, decreases towards edges.
            // (distCurrent / maxDistHypot) is 0 at center, 1 at corners.
            let vignetteFactor = 1.0 - Math.pow(distCurrent / maxDistHypot, vignettePower) * vignetteAmount;
            vignetteFactor = clamp(vignetteFactor, 0, 1); // Ensure factor is between 0 (full darken) and 1 (no change).

            r *= vignetteFactor;
            g *= vignetteFactor;
            b *= vignetteFactor;
        }

        // Final Clamping to ensure values are within the 0-255 range for RGB.
        data[i] = clamp(r, 0, 255);
        data[i+1] = clamp(g, 0, 255);
        data[i+2] = clamp(b, 0, 255);
        // Alpha channel (data[i+3]) remains unchanged.
    }

    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 Image 90s Retro Photo Filter tool allows users to enhance their images with a nostalgic 1990s visual style. This tool can apply various effects including adjusting contrast and brightness, adding a cool blue tint, simulating film grain, and creating a vignette effect that darkens the image edges. It’s perfect for users looking to transform their photos for creative projects, social media sharing, or simply to evoke a retro aesthetic.

Leave a Reply

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