Please bookmark this page to avoid losing your image tool!

Image To Matrix-style Falling Code Art Generator

(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,
    charSet = "ァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789",
    fontSize = 10,
    columnDensity = 1.0,
    glowColor = '#33FF33',
    trailColor = '#008000',
    backgroundColor = '#000000',
    brightnessThreshold = 30,
    leadingCharEmphasis = 1.5
) {
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');

    // Ensure numeric parameters are indeed numbers
    fontSize = Number(fontSize);
    columnDensity = Number(columnDensity);
    brightnessThreshold = Number(brightnessThreshold);
    leadingCharEmphasis = Number(leadingCharEmphasis);

    // Draw the original image to a temporary canvas to get its pixel data
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = originalImg.width;
    tempCanvas.height = originalImg.height;
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true }); // Hint for optimization if available
    tempCtx.drawImage(originalImg, 0, 0);
    const imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height).data;

    // Helper function to get brightness (luminance) of a pixel
    function getPixelBrightness(x, y, width, imgPixelData) {
        x = Math.floor(x);
        y = Math.floor(y);
        // Clamp coordinates to be within image bounds
        x = Math.max(0, Math.min(x, width - 1));
        y = Math.max(0, Math.min(y, Math.floor(imgPixelData.length / (width * 4)) - 1));
        
        const index = (y * width + x) * 4;
        const r = imgPixelData[index];
        const g = imgPixelData[index + 1];
        const b = imgPixelData[index + 2];
        // Standard luminance calculation
        return (0.299 * r + 0.587 * g + 0.114 * b);
    }

    // Fill background
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Prepare for drawing characters
    if (fontSize < 1) fontSize = 1; // Ensure minimum font size
    ctx.font = `${fontSize}px monospace`;
    ctx.textBaseline = 'top'; // Makes y-coordinate handling easier (y is top of char)

    const charsToUse = charSet.split('');
    if (charsToUse.length === 0) { // Prevent errors if charSet is empty
        charsToUse.push('X');
    }
    
    const baseColumnWidth = fontSize * 0.6; // Approx width of a monospace char relative to its height
    const actualColumnWidth = Math.max(1, baseColumnWidth / Math.max(0.1, columnDensity)); // Prevent division by zero or too small density
    const numColumns = Math.floor(canvas.width / actualColumnWidth);

    if (numColumns <= 0) { // If image too narrow or density settings result in no columns
        return canvas; // Return background-filled canvas
    }

    for (let i = 0; i < numColumns; i++) {
        const x = i * actualColumnWidth;
        
        // Each column gets a "stream" of characters.
        // For a static image, we simulate a snapshot of these streams.
        // Stream starts at a random y, potentially off-screen to simulate continuous flow.
        let streamStartY = Math.random() * canvas.height * 1.5 - canvas.height * 0.5; // Start y for char at j=0
        
        // Random length for this particular stream segment
        const streamLengthInChars = Math.floor(Math.random() * (canvas.height / fontSize / 1.5)) + Math.floor(fontSize / 2) + 3; // Adjusted length

        // Some streams might be designated as "brighter" overall, having more leading-style chars
        const isBrightStream = Math.random() < 0.15;

        for (let j = 0; j < streamLengthInChars; j++) {
            const charY = streamStartY + j * fontSize; // Top Y coordinate of the current character

            // Skip if character is completely out of visible canvas bounds
            if (charY < -fontSize || charY > canvas.height) {
                continue;
            }

            const randomChar = charsToUse[Math.floor(Math.random() * charsToUse.length)];

            // Determine position on original image to sample brightness (center of the character cell)
            const imageSampleX = x + actualColumnWidth / 2;
            const imageSampleY = charY + fontSize / 2; 

            const imgBrightness = getPixelBrightness(imageSampleX, imageSampleY, canvas.width, imageData);

            // If the underlying image area is too dark, apply a probability to skip drawing
            if (imgBrightness < brightnessThreshold && Math.random() > 0.2) { // 80% chance to skip if below threshold
                continue;
            }

            const normalizedImgBrightness = imgBrightness / 255.0; // Brightness as 0.0 - 1.0

            let charColorToUse;
            let charOpacity;
            let charShadowBlur = 0;
            let charShadowColor = 'transparent';

            // Determine if this character is a "leading" character (brightest one, typically at the head of the stream)
            // The first char in the stream (j=0) is always leading.
            // Others in a "bright stream" have diminishing chance to also be leading style.
            const isLeadingChar = (j === 0) || (isBrightStream && j < 3 && Math.random() < (0.6 - j * 0.2));
            
            if (isLeadingChar) {
                charColorToUse = glowColor;
                charOpacity = Math.min(1.0, normalizedImgBrightness * leadingCharEmphasis);
                charOpacity = Math.max(0.15, charOpacity); // Ensure minimum visibility for leading characters
                charShadowBlur = Math.max(1, normalizedImgBrightness * fontSize * 0.6); // Shadow relative to font size
                charShadowColor = glowColor;
            } else {
                charColorToUse = trailColor;
                // Fade trail characters based on position in stream and image brightness
                const trailFadeFactor = Math.pow((streamLengthInChars - j) / streamLengthInChars, 1.8); // Stronger fade for tail
                charOpacity = Math.min(1.0, normalizedImgBrightness * trailFadeFactor * 0.9); // Trail chars are dimmer
                charOpacity = Math.max(0.05, charOpacity); // Minimum visibility for trail characters
                charShadowBlur = Math.max(0, normalizedImgBrightness * trailFadeFactor * fontSize * 0.3);
                charShadowColor = trailColor;
            }
            
            ctx.fillStyle = charColorToUse;
            ctx.globalAlpha = charOpacity; // This will be clamped to [0,1] by canvas
            
            if (charShadowBlur > 0.5) { // Only apply shadow if it's somewhat visible
                ctx.shadowColor = charShadowColor;
                ctx.shadowBlur = charShadowBlur;
            } else {
                ctx.shadowBlur = 0; // Explicitly turn off shadow
                ctx.shadowColor = 'transparent';
            }
            
            ctx.fillText(randomChar, x, charY);
        }
    }
    
    // Reset global alpha and shadow settings that might affect subsequent drawings if canvas is reused elsewhere
    ctx.globalAlpha = 1.0;
    ctx.shadowBlur = 0;
    ctx.shadowColor = 'transparent';

    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 To Matrix-style Falling Code Art Generator transforms your images into visually striking artwork reminiscent of digital rain. By using a customizable character set, users can create a unique representation of their images, where pixels are replaced with characters that flow down the canvas in streams. This tool allows for adjustments in font size, column density, and color settings, enabling users to enhance the aesthetic according to their preferences. Ideal for artistic projects, digital designs, and creating engaging visuals for social media or presentations, this tool offers a creative way to reimagine images as fashionable code-like art.

Leave a Reply

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