Please bookmark this page to avoid losing your image tool!

Image Ancient Relic Filter Effect Tool

(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, sepiaIntensity = 0.8, noiseAmount = 25, vignetteStrength = 0.5, brightness = -20, contrast = 30) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // For performance with getImageData

    // Ensure dimensions are from naturalWidth/Height if available, fallback to width/height
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    // Handle zero-size images to prevent errors
    if (canvas.width === 0 || canvas.height === 0) {
        console.warn("Image has zero width or height.");
        return canvas; // Return empty canvas
    }

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

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This can happen if the image is tainted (e.g., cross-origin)
        console.error("Could not get image data (ensure image is not cross-origin or canvas is not tainted): ", e);
        // Optionally, draw a placeholder error message on the canvas
        ctx.font = "16px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Error: Cannot process image data.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    
    const data = imageData.data;

    // Pre-calculate values for vignette
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    // Using Math.hypot for cleaner code and potentially better precision for distance calculation.
    const maxImageRadius = Math.hypot(centerX, centerY); // Distance from center to a corner
    
    // Pre-calculate contrast factor
    // Map contrast GUI parameter (e.g., -100 to 100) to C_eff for the formula.
    let C_eff = contrast * 1.28; // scales -100..100 to -128..128 approx.
    // Clamp C_eff to prevent division by zero or overly extreme values.
    // The denominator (259 - C_eff) should not be zero.
    C_eff = Math.max(-258.999, Math.min(258.999, C_eff)); 
    
    let contrastFactor = 1; // Default to 1 (no change)
    if (contrast !== 0) {
        const denominator = 255 * (259 - C_eff);
        if (denominator === 0) { 
            // This case should be avoided by clamping C_eff. Set to a very large/small factor if it somehow occurs.
            contrastFactor = C_eff > 0 ? 1000 : 0.001; 
        } else {
            contrastFactor = (259 * (C_eff + 255)) / denominator;
        }
    }

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

        // 1. Sepia
        if (sepiaIntensity > 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);

            // Interpolate between original color and sepia color
            r = r * (1 - sepiaIntensity) + sr * sepiaIntensity;
            g = g * (1 - sepiaIntensity) + sg * sepiaIntensity;
            b = b * (1 - sepiaIntensity) + sb * sepiaIntensity;
        }

        // 2. Brightness
        if (brightness !== 0) {
            r += brightness;
            g += brightness;
            b += brightness;
        }

        // 3. Contrast
        if (contrast !== 0) {
            // The value 128 is the midpoint of the 0-255 range.
            r = contrastFactor * (r - 128) + 128;
            g = contrastFactor * (g - 128) + 128;
            b = contrastFactor * (b - 128) + 128;
        }
        
        // 4. Vignette
        if (vignetteStrength > 0 && maxImageRadius > 0) {
            const x = (i / 4) % canvas.width;
            const y = Math.floor((i / 4) / canvas.width);
            
            const dx = x - centerX;
            const dy = y - centerY;
            const distance = Math.hypot(dx, dy); // Distance of pixel from center
            
            const normalizedDistance = distance / maxImageRadius; // 0 at center, 1 at corners
            
            const vignettePower = 2.0; // Controls the falloff curve; 2.0 is quadratic
            const vignetteEffect = Math.pow(normalizedDistance, vignettePower); 
            
            // vignetteStrength (0-1) determines max reduction at corners
            const luminanceReduction = vignetteEffect * vignetteStrength;
            const pixelMultiplier = Math.max(0, 1.0 - luminanceReduction); // Ensure multiplier is not negative

            r *= pixelMultiplier;
            g *= pixelMultiplier;
            b *= pixelMultiplier;
        }

        // 5. Noise
        if (noiseAmount > 0) {
            // Add noise symmetrically around zero, e.g., if noiseAmount=20, noise is -10 to +10
            const randomNoiseR = (Math.random() - 0.5) * noiseAmount;
            const randomNoiseG = (Math.random() - 0.5) * noiseAmount;
            const randomNoiseB = (Math.random() - 0.5) * noiseAmount;
            
            r += randomNoiseR;
            g += randomNoiseG;
            b += randomNoiseB;
        }

        // Clamp final RGB values to [0, 255] and assign
        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));
        // 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 Ancient Relic Filter Effect Tool allows users to enhance their images by applying an array of vintage effects, including sepia toning, brightness adjustment, contrast enhancement, noise addition, and vignette effects. This tool is perfect for photographers, graphic designers, or anyone looking to give their digital images a nostalgic or historical feel, reminiscent of old photographs or ancient relics. It is particularly useful for creating thematic visuals, enhancing social media posts, or adding an artistic touch to personal projects.

Leave a Reply

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