Please bookmark this page to avoid losing your image tool!

Image Nuclear Fallout 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.
async function processImage(originalImg, contrastLevel = 70, noiseLevel = 25, tintColorStr = "150,160,50", tintStrength = 0.3) {
    // 1. Canvas setup
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Ensure image is loaded for naturalWidth/naturalHeight, otherwise use width/height
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    if (imgWidth === 0 || imgHeight === 0) {
        // Image has no dimensions, return an empty canvas or indicate error
        console.warn("Input image has zero width or height.");
        canvas.width = 100; // Default small size for error message
        canvas.height = 50;
        ctx.font = "12px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Invalid image dimensions.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }

    canvas.width = imgWidth;
    canvas.height = imgHeight;
    
    try {
        ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Error drawing image onto canvas:", e);
        ctx.font = "16px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Error: Could not draw image.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }


    // 2. Get imageData
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This can happen if the image is from a different origin and canvas is tainted
        console.error("Could not get image data (cross-origin issue?):", e);
        // Clear canvas and draw an error message
        ctx.clearRect(0, 0, canvas.width, canvas.height); 
        ctx.font = "16px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Error: Cannot process cross-origin image.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    
    const data = imageData.data;

    // Parse tintColorStr and validate parameters
    let [tintR, tintG, tintB] = tintColorStr.split(',').map(s => parseInt(s, 10));

    if (isNaN(tintR) || isNaN(tintG) || isNaN(tintB) || tintColorStr.split(',').length !== 3) {
        [tintR, tintG, tintB] = [150, 160, 50]; // Default fallback tint (sickly green-yellow)
    }
    tintR = Math.max(0, Math.min(255, tintR));
    tintG = Math.max(0, Math.min(255, tintG));
    tintB = Math.max(0, Math.min(255, tintB));
    
    // Ensure numeric types and clamp values for other parameters
    contrastLevel = Number(contrastLevel);
    noiseLevel = Number(noiseLevel);
    tintStrength = Number(tintStrength);

    // Clamp contrastLevel: The formula used works well with -255 to 255.
    // Values outside this range can lead to factors that are too extreme or problematic.
    contrastLevel = Math.max(-255, Math.min(255, contrastLevel)); 
    
    // Clamp tintStrength to [0, 1] (0 = no tint, 1 = full tint)
    tintStrength = Math.max(0, Math.min(1, tintStrength));
    
    // Noise level should be non-negative
    noiseLevel = Math.max(0, noiseLevel);

    // 3. Iterate pixel by pixel
    for (let i = 0; i < data.length; i += 4) {
        let r_orig = data[i];
        let g_orig = data[i + 1];
        let b_orig = data[i + 2];

        // a. Grayscale (Luminosity method: 0.299R + 0.587G + 0.114B)
        let L = 0.299 * r_orig + 0.587 * g_orig + 0.114 * b_orig;

        // b. Contrast
        // Formula: factor = (259 * (C + 255)) / (255 * (259 - C))
        // AdjustedPixel = factor * (L_original_component - 128) + 128
        // C is contrastLevel, clamped between -255 and 255.
        // If C = 0, factor = 1 (no change).
        // If C = 255, factor yields high contrast. If C = -255, factor = 0 (results in gray 128).
        const contrastFactor = (259 * (contrastLevel + 255)) / (255 * (259 - contrastLevel));
        
        L = contrastFactor * (L - 128) + 128;
        L = Math.max(0, Math.min(255, L)); // Clamp Luminance to [0, 255]

        // c. Tint application
        // Linearly interpolate between the grayscale value (L) and the tint color
        let R_final = L * (1 - tintStrength) + tintR * tintStrength;
        let G_final = L * (1 - tintStrength) + tintG * tintStrength;
        let B_final = L * (1 - tintStrength) + tintB * tintStrength;
        
        // d. Noise application
        // Add random noise, distributed around 0, scaled by noiseLevel
        const noise = (Math.random() - 0.5) * 2 * noiseLevel; 
        R_final += noise;
        G_final += noise;
        B_final += noise;

        // Clamp final RGB values to [0, 255]
        data[i] = Math.max(0, Math.min(255, R_final));
        data[i + 1] = Math.max(0, Math.min(255, G_final));
        data[i + 2] = Math.max(0, Math.min(255, B_final));
        // Alpha channel (data[i+3]) remains unchanged
    }

    // 4. Put modified imageData back to canvas
    ctx.putImageData(imageData, 0, 0);

    // 5. Return the canvas element
    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 Nuclear Fallout Filter Effect Tool allows users to apply a distinctive filter resembling a nuclear fallout effect to their images. This tool enables customization through parameters such as contrast level, noise level, and tint color, allowing users to achieve a desaturated and tinted look reminiscent of post-apocalyptic imagery. It is suitable for creative projects, artistic expressions, and visual storytelling, making it useful for photographers, graphic designers, and content creators looking to enhance their images with unique filters.

Leave a Reply

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