Please bookmark this page to avoid losing your image tool!

Image Patina Effect Adder For Old Cars

(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.
async function processImage(originalImg, intensity = 0.5, rustColor = '#8b4513', dustColor = '#c2b280', scratchCount = 75, noiseAmount = 0.15) {

    /**
     * Helper function to convert a hex color string to an RGB object.
     * @param {string} hex - The hex color string (e.g., '#RRGGBB').
     * @returns {{r: number, g: number, b: number}|null} An object with r, g, b properties, or null if invalid.
     */
    const hexToRgb = (hex) => {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
        } : null;
    };

    const rustRgb = hexToRgb(rustColor);
    const dustRgb = hexToRgb(dustColor);

    if (!rustRgb || !dustRgb) {
        console.error("Invalid hex color provided.");
        return originalImg;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    // --- 1. Generate a noise map to control rust and dust placement ---
    const noiseCanvas = document.createElement('canvas');
    const noiseCtx = noiseCanvas.getContext('2d');
    const noiseSize = Math.max(32, Math.floor(canvas.width / 20)); // Low resolution noise
    noiseCanvas.width = noiseSize;
    noiseCanvas.height = Math.floor(noiseSize * (canvas.height / canvas.width));
    
    const noiseImageData = noiseCtx.createImageData(noiseCanvas.width, noiseCanvas.height);
    const noiseData = noiseImageData.data;
    for (let i = 0; i < noiseData.length; i += 4) {
        const value = Math.random() * 255;
        noiseData[i] = value;
        noiseData[i + 1] = value;
        noiseData[i + 2] = value;
        noiseData[i + 3] = 255;
    }
    noiseCtx.putImageData(noiseImageData, 0, 0);

    // Scale up the noise to create a blotchy mask
    const maskCanvas = document.createElement('canvas');
    const maskCtx = maskCanvas.getContext('2d');
    maskCanvas.width = canvas.width;
    maskCanvas.height = canvas.height;
    maskCtx.imageSmoothingEnabled = true;
    maskCtx.drawImage(noiseCanvas, 0, 0, maskCanvas.width, maskCanvas.height);
    const maskData = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height).data;


    // --- 2. Draw the original image and manipulate pixels ---
    ctx.drawImage(originalImg, 0, 0);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    const rustThreshold = 0.6;
    const dustThreshold = 0.4;
    const clampedIntensity = Math.max(0, Math.min(1, intensity));

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

        // --- a. Fading: Desaturate and apply a slight sepia tone ---
        const gray = r * 0.299 + g * 0.587 + b * 0.114;
        const desatFactor = clampedIntensity * 0.7;
        r = r * (1 - desatFactor) + gray * desatFactor;
        g = g * (1 - desatFactor) + gray * desatFactor;
        b = b * (1 - desatFactor) + gray * desatFactor;

        const sepiaFactor = clampedIntensity * 0.4;
        const tr = r * 0.393 + g * 0.769 + b * 0.189;
        const tg = r * 0.349 + g * 0.686 + b * 0.168;
        const tb = r * 0.272 + g * 0.534 + b * 0.131;
        r = r * (1 - sepiaFactor) + tr * sepiaFactor;
        g = g * (1 - sepiaFactor) + tg * sepiaFactor;
        b = b * (1 - sepiaFactor) + tb * sepiaFactor;

        // --- b. Apply rust and dust using the noise mask ---
        const maskValue = maskData[i] / 255;

        // Apply Rust to bright areas of the noise mask
        if (maskValue > rustThreshold) {
            const rustAmount = ((maskValue - rustThreshold) / (1 - rustThreshold)) * clampedIntensity;
            r = r * (1 - rustAmount) + rustRgb.r * rustAmount;
            g = g * (1 - rustAmount) + rustRgb.g * rustAmount;
            b = b * (1 - rustAmount) + rustRgb.b * rustAmount;
        } 
        
        // Apply Dust to dark areas of the noise mask
        if (maskValue < dustThreshold) {
            const dustAmount = ((dustThreshold - maskValue) / dustThreshold) * clampedIntensity * 0.8;
            r = r * (1 - dustAmount) + dustRgb.r * dustAmount;
            g = g * (1 - dustAmount) + dustRgb.g * dustAmount;
            b = b * (1 - dustAmount) + dustRgb.b * dustAmount;
        }

        // --- c. Add fine grain noise ---
        const noise = (Math.random() - 0.5) * 255 * noiseAmount;
        r += noise;
        g += noise;
        b += noise;

        // Clamp values and update image data
        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));
    }

    ctx.putImageData(imageData, 0, 0);

    // --- 3. Draw scratches on top ---
    for (let i = 0; i < scratchCount; i++) {
        const x1 = Math.random() * canvas.width;
        const y1 = Math.random() * canvas.height;
        const length = (Math.random() * canvas.width) / 20;
        const angle = Math.random() * Math.PI * 2;
        const x2 = x1 + Math.cos(angle) * length;
        const y2 = y1 + Math.sin(angle) * length;
        
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        
        const isLight = Math.random() > 0.5;
        ctx.strokeStyle = isLight ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
        ctx.lineWidth = Math.random() * 1.5 + 0.5;
        ctx.stroke();
    }

    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 Patina Effect Adder for Old Cars is a web tool designed to apply a vintage patina effect to images of vehicles. This tool allows users to transform their pictures by adding effects such as rust, dust, and scratches, which simulate the wear and tear often found on older cars. By adjusting parameters like intensity, rust color, and scratch count, users can customize the appearance of the image to achieve the desired level of patina. This tool is ideal for car enthusiasts, photographers, and graphic designers looking to enhance automotive images with a nostalgic or rugged aesthetic.

Leave a Reply

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