Please bookmark this page to avoid losing your image tool!

Image To ASCII Text Art Converter

(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.
/**
 * Converts an image to ASCII text art and renders it on a canvas.
 * The function downsamples the image, maps pixel brightness to a character
 * from a given set, and then draws the resulting text onto a new canvas.
 *
 * @param {HTMLImageElement} originalImg The source image object. Must be fully loaded.
 * @param {number} [maxWidth=120] The maximum width of the ASCII art in characters. The height is determined by the image's aspect ratio.
 * @param {string} [characterSet="@#S%?*+;:,. "] The set of characters to use for rendering, ordered from densest (for dark areas) to sparsest (for light areas).
 * @returns {HTMLCanvasElement} A canvas element with the ASCII art drawn on it.
 */
function processImage(originalImg, maxWidth = 120, characterSet = "@#S%?*+;:,. ") {
    // 1. Validate parameters
    if (!(originalImg instanceof HTMLImageElement) || !originalImg.width || !originalImg.height) {
        throw new Error("The first parameter must be a loaded HTMLImageElement object.");
    }
    if (typeof maxWidth !== 'number' || maxWidth <= 0) {
        maxWidth = 120;
    }
    if (typeof characterSet !== 'string' || characterSet.length === 0) {
        characterSet = "@#S%?*+;:,. ";
    }

    // This constant is used to correct the aspect ratio because characters in monospace
    // fonts are typically taller than they are wide. A value of 0.5 is a good starting point.
    const FONT_ASPECT_RATIO = 0.5;
    const FONT_SIZE = 10;
    const FONT_FAMILY = 'monospace';

    // 2. Calculate the dimensions for the downsampled ASCII grid
    const aspectRatio = originalImg.height / originalImg.width;
    const newWidth = Math.floor(Math.min(maxWidth, originalImg.width));
    const newHeight = Math.floor(newWidth * aspectRatio * FONT_ASPECT_RATIO);

    if (newWidth === 0 || newHeight === 0) {
        console.error("Image is too small to process with the given parameters.");
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = 300;
        errorCanvas.height = 50;
        const errCtx = errorCanvas.getContext('2d');
        errCtx.font = '14px sans-serif';
        errCtx.fillStyle = 'red';
        errCtx.fillText('Error: Image is too small to process.', 10, 30);
        return errorCanvas;
    }

    // 3. Create a temporary canvas to downsample the image and get its pixel data
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = newWidth;
    tempCanvas.height = newHeight;
    const tempCtx = tempCanvas.getContext('2d', {
        willReadFrequently: true
    });
    tempCtx.drawImage(originalImg, 0, 0, newWidth, newHeight);
    const imageData = tempCtx.getImageData(0, 0, newWidth, newHeight).data;

    // 4. Generate the ASCII character lines based on pixel brightness
    const asciiLines = [];
    for (let y = 0; y < newHeight; y++) {
        let line = '';
        for (let x = 0; x < newWidth; x++) {
            const i = (y * newWidth + x) * 4;
            const r = imageData[i];
            const g = imageData[i + 1];
            const b = imageData[i + 2];

            // Convert pixel to grayscale using the luminosity formula for perceived brightness
            const gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;

            // Map the brightness (0-255) to an index in the character set
            const charIndex = Math.floor((gray / 255) * (characterSet.length - 1));
            line += characterSet[charIndex] || ' '; // Fallback to a space
        }
        asciiLines.push(line);
    }

    // 5. Create the final output canvas and render the ASCII text
    const outputCanvas = document.createElement('canvas');
    const outputCtx = outputCanvas.getContext('2d');
    outputCtx.font = `${FONT_SIZE}px ${FONT_FAMILY}`;

    // Measure character dimensions to precisely size the final canvas
    const metrics = outputCtx.measureText('@'); // Use a representative character for width
    const charWidth = metrics.width;
    const lineHeight = FONT_SIZE; // Line height can be the same as font size for a tight grid

    outputCanvas.width = Math.ceil(newWidth * charWidth);
    outputCanvas.height = Math.ceil(newHeight * lineHeight);

    // Set background and font styles (context state is reset after resizing)
    outputCtx.fillStyle = 'white';
    outputCtx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);

    outputCtx.font = `${FONT_SIZE}px ${FONT_FAMILY}`;
    outputCtx.fillStyle = 'black';
    outputCtx.textBaseline = 'top'; // Align text to the top for predictable line placement

    // Draw each line of ASCII text onto the canvas
    for (let i = 0; i < asciiLines.length; i++) {
        outputCtx.fillText(asciiLines[i], 0, i * lineHeight);
    }

    // 6. Return the final canvas element
    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 To ASCII Text Art Converter is a tool that transforms images into ASCII art representations. It allows users to input an image, which is downscaled and processed to map pixel brightness levels to a selected set of ASCII characters. This conversion generates a canvas displaying the ASCII art that closely resembles the original image. Use cases for this tool include creating unique text-based artwork, enhancing web design with retro aesthetics, or making images suitable for display in environments where graphics may not be supported.

Leave a Reply

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