Please bookmark this page to avoid losing your image tool!

Image Matrix Code Rain 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,
    fontSize = 16,
    fontColor = "lime",
    trailColor = "rgba(0, 0, 0, 0.05)",
    characterType = "katakana_numbers", // Options: "katakana_numbers", "alphanumeric", "binary", "numbers", "katakana"
    fallSpeed = 1,
    resetProbability = 0.02
) {
    // Ensure numeric parameters are numbers and have valid ranges/defaults
    fontSize = Number(fontSize);
    if (isNaN(fontSize) || fontSize <= 0) {
        fontSize = 16;
    }

    fallSpeed = Number(fallSpeed);
    if (isNaN(fallSpeed) || fallSpeed <= 0) {
        fallSpeed = 1;
    }

    resetProbability = Number(resetProbability);
    if (isNaN(resetProbability) || resetProbability < 0 || resetProbability > 1) {
        resetProbability = isNaN(resetProbability) ? 0.02 : Math.max(0, Math.min(1, resetProbability));
    }
    
    characterType = String(characterType); // Ensure characterType is a string for the switch

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { alpha: false }); // alpha: false assuming trailColor effectively makes it opaque

    // Use naturalWidth/Height if available for the image, fallback to width/height
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;
    
    // Handle cases where image dimensions might be problematic
    if (canvas.width === 0 || canvas.height === 0) {
        canvas.width = canvas.width || 100; // Ensure some dimension if original was 0
        canvas.height = canvas.height || 100;
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        // Attempt to draw an error message on the placeholder canvas
        if (typeof ctx.fillText === 'function') {
            ctx.fillStyle = "red";
            ctx.font = "12px sans-serif";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillText("Error: Image zero size", canvas.width / 2, canvas.height / 2);
        }
        return canvas;
    }

    // Draw the original image ONCE as the initial background.
    try {
        ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    } catch (e) {
        // Fallback: fill canvas with black if image drawing fails (e.g. tainted canvas)
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        if (typeof ctx.fillText === 'function') {
            ctx.fillStyle = "red";
            ctx.font = "12px sans-serif";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillText("Error: Couldn't draw image", canvas.width/2, canvas.height/2);
        }
        return canvas; // Early exit if image can't be drawn
    }

    // Define character sets
    const KATAKANA_SET = "アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン";
    const NUMBERS_SET = "0123456789";
    const ALPHANUMERIC_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + NUMBERS_SET;
    const BINARY_SET = "01";

    let charSet = "";
    switch (characterType.toLowerCase()) {
        case "katakana_numbers":
            charSet = KATAKANA_SET + NUMBERS_SET;
            break;
        case "alphanumeric":
            charSet = ALPHANUMERIC_SET;
            break;
        case "binary":
            charSet = BINARY_SET;
            break;
        case "numbers":
            charSet = NUMBERS_SET;
            break;
        case "katakana":
            charSet = KATAKANA_SET;
            break;
        default:
            charSet = KATAKANA_SET + NUMBERS_SET; // Default if unknown type
    }

    // Ensure charSet is not empty
    if (charSet.length === 0) {
        charSet = NUMBERS_SET;
    }
    
    const numColumns = Math.floor(canvas.width / fontSize);
    
    // If canvas is too narrow for any columns, apply trail and return
    if (numColumns <= 0) {
        ctx.fillStyle = trailColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        return canvas;
    }

    // Initialize drops: y-coordinate (in fontSize blocks) for the leading char of each column
    const drops = [];
    for (let i = 0; i < numColumns; i++) {
        // Start drops at random negative y-positions (staggered above the canvas)
        // Stagger depth is somewhat proportional to the number of columns.
        drops[i] = -(Math.random() * numColumns * 0.8);
    }

    function drawMatrix() {
        // Apply trailColor: fills the canvas, creating a fading effect for previous characters
        // and continuously fading the original background image.
        ctx.fillStyle = trailColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        ctx.fillStyle = fontColor;
        ctx.font = `${fontSize}px monospace`; // Monospace for grid-like character alignment

        for (let i = 0; i < numColumns; i++) {
            const charIndex = Math.floor(Math.random() * charSet.length);
            const text = charSet[charIndex];
            
            const xPos = i * fontSize;
            const yPos = drops[i] * fontSize;

            ctx.fillText(text, xPos, yPos);

            // Check if the drop's y-position is past the canvas height
            if (yPos > canvas.height) {
                // If so, and a random chance is met (based on resetProbability), reset the drop.
                if (Math.random() < resetProbability) {
                    // Reset to a staggered position slightly above the canvas.
                    drops[i] = -(Math.random() * numColumns * 0.2); 
                }
                // If resetProbability is 0, or the random chance isn't met, the drop continues
                // falling further down. It will only reset if resetProbability > 0 and the chance occurs.
            }
            
            drops[i] += fallSpeed; // Move the drop down for the next frame
        }
        
        requestAnimationFrame(drawMatrix); // Continue the animation loop
    }
    
    drawMatrix(); // Start the animation

    return canvas; // Return the canvas, on which the animation is continuously drawing
}

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 Matrix Code Rain Filter Effect Tool allows users to apply a dynamic visual effect reminiscent of the iconic ‘Matrix’ code rain to their images. This tool transforms the original image into a flowing backdrop of falling characters, which can be customized with varying font sizes, colors, speed, and character sets. Use cases include enhancing digital artwork, creating background visuals for videos, or simply adding a creative overlay to images for social media posts. The tool’s settings allow for various styles from alphanumeric characters to katakana and binary representations, making it versatile for different artistic preferences.

Leave a Reply

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