Please bookmark this page to avoid losing your image tool!

Image Secret Code 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, charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&?", fontSize = 10) {
    // Ensure originalImg is a usable Image object (basic check)
    if (!originalImg || typeof originalImg.naturalWidth === 'undefined' || typeof originalImg.naturalHeight === 'undefined') {
        console.error("processImage: Invalid originalImg object provided.");
        const errCanvas = document.createElement('canvas');
        errCanvas.width = 300; 
        errCanvas.height = 150;
        const errCtx = errCanvas.getContext('2d');
        if (errCtx) {
            // Simple error display on the canvas
            errCtx.fillStyle = '#F0F0F0'; // Light gray background
            errCtx.fillRect(0, 0, errCanvas.width, errCanvas.height);
            errCtx.fillStyle = '#333333'; // Dark gray text
            errCtx.font = '16px Arial';
            errCtx.textAlign = 'center';
            errCtx.textBaseline = 'middle';
            errCtx.fillText('Error: Invalid image input.', errCanvas.width / 2, errCanvas.height / 2);
        }
        return errCanvas;
    }

    // Validate and set default parameters
    const effectiveCharSet = (typeof charSet === 'string' && charSet.length > 0) ? charSet : "01";
    let numFontSize = Number(fontSize);
    if (isNaN(numFontSize) || numFontSize <= 0) {
        numFontSize = 10; // Default font size if invalid
    }

    const imgWidth = originalImg.naturalWidth;
    const imgHeight = originalImg.naturalHeight;

    // Handle cases where image might not be loaded or has no dimensions
    if (imgWidth === 0 || imgHeight === 0) {
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = Math.max(1, imgWidth); // Ensure at least 1x1
        emptyCanvas.height = Math.max(1, imgHeight);
        return emptyCanvas;
    }

    // Create a temporary canvas to draw the original image and get its pixel data
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = imgWidth;
    tempCanvas.height = imgHeight;
    const tempCtx = tempCanvas.getContext('2d');

    if (!tempCtx) {
        console.error("processImage: Could not get 2D context from temporary canvas.");
        const errCanvas = document.createElement('canvas');
        errCanvas.width = imgWidth; errCanvas.height = imgHeight;
        const errCtx = errCanvas.getContext('2d');
        if (errCtx) {
            errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
            errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
            errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
            errCtx.fillText('Error: Canvas context failed (temp).', imgWidth / 2, imgHeight / 2);
        }
        return errCanvas;
    }

    tempCtx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("processImage: Error getting imageData (possibly CORS issue):", e);
        const errCanvas = document.createElement('canvas');
        errCanvas.width = imgWidth; errCanvas.height = imgHeight;
        const errCtx = errCanvas.getContext('2d');
        if (errCtx) {
            errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
            errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
            errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
            errCtx.fillText('Error: Cannot access image pixels.', imgWidth / 2, imgHeight / 2 - 10);
            errCtx.fillText('(Possibly cross-origin image)', imgWidth / 2, imgHeight / 2 + 10);
        }
        return errCanvas;
    }
    const data = imageData.data;

    // Create the output canvas
    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = imgWidth;
    outputCanvas.height = imgHeight;
    const ctx = outputCanvas.getContext('2d');

    if (!ctx) {
        console.error("processImage: Could not get 2D context from output canvas.");
        const errCanvas = document.createElement('canvas');
        errCanvas.width = imgWidth; errCanvas.height = imgHeight;
        const errCtx = errCanvas.getContext('2d');
        if (errCtx) {
            errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
            errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
            errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
            errCtx.fillText('Error: Canvas context failed (output).', imgWidth / 2, imgHeight / 2);
        }
        return errCanvas;
    }

    // Set text properties for drawing characters
    // Using monospace font ensures characters align somewhat in a grid
    ctx.font = `${numFontSize}px monospace`;
    ctx.textAlign = 'left';   // Characters drawn from top-left of their "cell"
    ctx.textBaseline = 'top';

    // Iterate over the image in a grid pattern based on fontSize
    for (let y = 0; y < imgHeight; y += numFontSize) {
        for (let x = 0; x < imgWidth; x += numFontSize) {
            // Determine the center of the current cell to sample a pixel color
            const sampleX = Math.min(Math.floor(x + numFontSize / 2), imgWidth - 1);
            const sampleY = Math.min(Math.floor(y + numFontSize / 2), imgHeight - 1);

            // Get RGBA components of the sampled pixel
            const pixelIndex = (sampleY * imgWidth + sampleX) * 4;
            const r = data[pixelIndex];
            const g = data[pixelIndex + 1];
            const b = data[pixelIndex + 2];
            const a = data[pixelIndex + 3];

            // If the sampled pixel's alpha is very low, skip drawing a character
            // This helps preserve transparency from the original image.
            // A_THRESHOLD (e.g., 25 means alpha < ~10%)
            const ALPHA_THRESHOLD = 25; 
            if (a < ALPHA_THRESHOLD) {
                continue; 
            }

            // Select a random character from the provided character set
            const charIndex = Math.floor(Math.random() * effectiveCharSet.length);
            const char = effectiveCharSet[charIndex];
            
            // Set the fill style (color and alpha) for the character
            // to match the sampled pixel from the original image.
            ctx.fillStyle = `rgba(${r},${g},${b},${a / 255})`;
            
            // Draw the character at the top-left of the current grid cell
            ctx.fillText(char, x, y);
        }
    }

    return outputCanvas;
}

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 Secret Code Filter Effect Tool allows users to transform images into a grid of randomly selected characters that represent the colors of the original image. By specifying a character set and font size, users can create unique visual effects suitable for artistic projects, code-themed designs, or digital art. This tool can be useful for creating stylish graphics for websites, social media posts, or other creative applications where a text-based representation of images is desired.

Leave a Reply

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