Please bookmark this page to avoid losing your image tool!

Image To Square Black Symbol 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.
function processImage(originalImg, resolution = 10, threshold = 128, fontSize = 10, fontColor = 'black', backgroundColor = 'white') {
    // 1. Create a temporary canvas to draw the image and access its pixel data
    const tempCanvas = document.createElement('canvas');
    // The willReadFrequently attribute can optimize performance for repeated getImageData calls.
    const tempCtx = tempCanvas.getContext('2d', {
        willReadFrequently: true
    });

    // Use naturalWidth/Height to get the original image dimensions, unaffected by CSS styling
    tempCanvas.width = originalImg.naturalWidth;
    tempCanvas.height = originalImg.naturalHeight;
    tempCtx.drawImage(originalImg, 0, 0);

    // 2. Get the pixel data from the temporary canvas
    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
    } catch (e) {
        // Handle potential security errors (tainted canvas from cross-origin images)
        console.error("Could not get image data. This may be due to a cross-origin security restriction.", e);
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = 400;
        errorCanvas.height = 120;
        const errorCtx = errorCanvas.getContext('2d');
        errorCtx.fillStyle = '#f0f0f0';
        errorCtx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
        errorCtx.fillStyle = 'red';
        errorCtx.font = 'bold 16px sans-serif';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        errorCtx.fillText('Error: Could not process the image.', errorCanvas.width / 2, 35);
        errorCtx.font = '14px sans-serif';
        errorCtx.fillText('The image might be from another website (cross-origin).', errorCanvas.width / 2, 65);
        errorCtx.fillText('Please use an image from the same domain or a CORS-enabled server.', errorCanvas.width / 2, 85);
        return errorCanvas;
    }
    const data = imageData.data;

    // 3. Sanitize and validate input parameters
    resolution = Math.max(1, Number(resolution) || 10);
    threshold = Math.max(0, Math.min(255, Number(threshold) || 128));
    fontSize = Math.max(1, Number(fontSize) || 10);

    // 4. Calculate dimensions for the output canvas based on resolution and font size
    const cols = Math.floor(tempCanvas.width / resolution);
    const rows = Math.floor(tempCanvas.height / resolution);

    const outputCanvas = document.createElement('canvas');
    const outputCtx = outputCanvas.getContext('2d');

    // Use a generic monospace font for consistent grid-like alignment
    const font = `${fontSize}px monospace`;
    outputCtx.font = font;

    // Measure the actual rendered width of the character for accurate spacing.
    // For height, using the font size provides consistent line spacing.
    const charWidth = outputCtx.measureText('■').width;
    const charHeight = fontSize;

    outputCanvas.width = Math.max(1, cols * charWidth);
    outputCanvas.height = Math.max(1, rows * charHeight);

    // 5. Set up the styles for the output canvas
    outputCtx.fillStyle = backgroundColor;
    outputCtx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);

    outputCtx.fillStyle = fontColor;
    outputCtx.font = font;
    outputCtx.textAlign = 'left';
    outputCtx.textBaseline = 'top';

    // 6. Iterate through the image in blocks determined by the resolution
    for (let y = 0; y < rows; y++) {
        for (let x = 0; x < cols; x++) {
            const startX = x * resolution;
            const startY = y * resolution;

            let totalLuminance = 0;
            let pixelCount = 0;

            // Calculate the average brightness (luminance) of the current block
            for (let blockY = 0; blockY < resolution; blockY++) {
                for (let blockX = 0; blockX < resolution; blockX++) {
                    const currentX = startX + blockX;
                    const currentY = startY + blockY;

                    if (currentX < tempCanvas.width && currentY < tempCanvas.height) {
                        const pixelIndex = (currentY * tempCanvas.width + currentX) * 4;
                        const r = data[pixelIndex];
                        const g = data[pixelIndex + 1];
                        const b = data[pixelIndex + 2];
                        // Using the perceived luminance formula for a more accurate grayscale representation
                        const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
                        totalLuminance += luminance;
                        pixelCount++;
                    }
                }
            }

            if (pixelCount === 0) continue;

            const avgLuminance = totalLuminance / pixelCount;

            // 7. If the block's average brightness is below the threshold, draw a square symbol
            if (avgLuminance < threshold) {
                outputCtx.fillText('■', x * charWidth, y * charHeight);
            }
        }
    }

    // 8. 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 Square Black Symbol Converter transforms an image into a grid of square symbols based on the luminance of the original pixels. Users can adjust the resolution, threshold for brightness, and the size and color of the symbols. This tool is useful for creating stylized representations of images, generating unique graphical art, or developing representations that can be printed or used in digital formats where a textured look is desired.

Leave a Reply

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