Please bookmark this page to avoid losing your image tool!

Image Text Alphabetical Translator

(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.
/**
 * Translates an image into a text-based representation by mapping pixel brightness to characters from a given alphabet.
 * This is similar to ASCII art. The function can dynamically load Google Fonts if specified.
 *
 * @param {Image} originalImg The original HTML Image object to process.
 * @param {string} [alphabet="$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "] The string of characters used for translation. The characters should be ordered from most visually dense (for dark areas) to least dense (for light areas).
 * @param {number} [blockSize=10] The size (in pixels) of each square block of the image to be converted into a single character. Smaller values result in higher detail.
 * @param {number} [fontSize=10] The font size (in pixels) for the output characters. For a grid-like effect, this should typically be close to the blockSize.
 * @param {string} [fontFamily='monospace'] The font to use for the characters. Monospaced fonts work best. Can be a web-safe font (e.g., 'monospace', 'Courier New') or a Google Font (e.g., 'Roboto Mono', 'Source Code Pro').
 * @param {string} [backgroundColor='#ffffff'] The background color of the output canvas, in a CSS-compatible format.
 * @param {string} [textColor='#000000'] The color of the text characters, in a CSS-compatible format.
 * @returns {Promise<HTMLCanvasElement>} A Promise that resolves to a canvas element containing the generated text art.
 */
async function processImage(originalImg, alphabet = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ", blockSize = 10, fontSize = 10, fontFamily = 'monospace', backgroundColor = '#ffffff', textColor = '#000000') {

    // Helper function to dynamically load a font if it's not a standard web-safe font.
    const loadFontIfNeeded = async (font, size) => {
        const genericFonts = ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy'];
        if (genericFonts.includes(font.toLowerCase())) {
            return; // No need to load generic fonts.
        }

        try {
            if (document.fonts && !(await document.fonts.check(`${size}px ${font}`))) {
                const fontUrl = `https://fonts.googleapis.com/css2?family=${font.replace(/ /g, '+')}&display=swap`;

                // Avoid adding duplicate links to the head.
                if (!document.querySelector(`link[href="${fontUrl}"]`)) {
                    const link = document.createElement('link');
                    link.href = fontUrl;
                    link.rel = 'stylesheet';
                    document.head.appendChild(link);
                    // Wait for the font to be ready.
                    await document.fonts.load(`${size}px ${font}`);
                }
            }
        } catch (e) {
            console.error(`Failed to load font: ${font}. Falling back to monospace.`, e);
            fontFamily = 'monospace'; // Fallback in case of an error.
        }
    };

    // Ensure the specified font is loaded before we start drawing.
    await loadFontIfNeeded(fontFamily, fontSize);

    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } can optimize repeated getImageData calls.
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });

    // Calculate canvas dimensions to be an exact multiple of the block size.
    const numCols = Math.floor(originalImg.width / blockSize);
    const numRows = Math.floor(originalImg.height / blockSize);
    canvas.width = numCols * blockSize;
    canvas.height = numRows * blockSize;

    // Create a temporary in-memory canvas to get pixel data from a scaled version of the image.
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = canvas.width;
    tempCanvas.height = canvas.height;
    const tempCtx = tempCanvas.getContext('2d');

    // Draw the image onto the temporary canvas, scaling it to our target dimensions.
    tempCtx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    const imageData = tempCtx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    // Prepare the main canvas for drawing.
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = textColor;
    ctx.font = `${fontSize}px ${fontFamily}`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // Process the image block by block.
    for (let y = 0; y < numRows; y++) {
        for (let x = 0; x < numCols; x++) {
            const startX = x * blockSize;
            const startY = y * blockSize;

            let totalBrightness = 0;
            const pixelCount = blockSize * blockSize;

            // Calculate the average brightness for the current block.
            for (let blockY = 0; blockY < blockSize; blockY++) {
                for (let blockX = 0; blockX < blockSize; blockX++) {
                    const pixelX = startX + blockX;
                    const pixelY = startY + blockY;
                    const dataIndex = (pixelY * canvas.width + pixelX) * 4;

                    const r = data[dataIndex];
                    const g = data[dataIndex + 1];
                    const b = data[dataIndex + 2];

                    // Use the luminosity formula for a perceptually accurate grayscale value.
                    const brightness = 0.299 * r + 0.587 * g + 0.114 * b;
                    totalBrightness += brightness;
                }
            }

            const avgBrightness = totalBrightness / pixelCount;

            // Map the average brightness (0-255) to a character in the provided alphabet.
            const charIndex = Math.floor((avgBrightness / 255) * (alphabet.length - 1));
            const char = alphabet.charAt(charIndex);

            // Draw the selected character in the center of the block.
            if (char) {
                const drawX = startX + blockSize / 2;
                const drawY = startY + blockSize / 2;
                ctx.fillText(char, drawX, drawY);
            }
        }
    }

    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 Text Alphabetical Translator converts images into a text-based representation by mapping pixel brightness to a specified set of characters. This tool is similar to ASCII art, allowing users to create unique visual representations of images using characters. It offers customizable options for character sets, block sizes, font sizes, and colors, making it useful for creative projects, graphical design, and digital art. Users can transform their images into artistic text forms suitable for sharing online, creating visual content for social media, or enhancing personal websites.

Leave a Reply

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