Please bookmark this page to avoid losing your image tool!

Image Text Generator From Text Query

(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,
    textQuery = "Введите запрос",
    mode = "typography",
    fontSize = 16,
    fontColor = "#FFFFFF",
    backgroundColor = "#000000"
) {
    const canvas = document.createElement("canvas");
    const width = originalImg.width;
    const height = originalImg.height;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext("2d");

    // Ensure a reasonable minimum font size to prevent extreme performance issues
    const parsedFontSize = Math.max(4, parseInt(fontSize, 10)) || 16;
    
    if (mode === "typography") {
        const tempCanvas = document.createElement("canvas");
        tempCanvas.width = width;
        tempCanvas.height = height;
        const tempCtx = tempCanvas.getContext("2d");
        
        // Draw the image to read its pixels
        tempCtx.drawImage(originalImg, 0, 0, width, height);

        let imageData;
        try {
            imageData = tempCtx.getImageData(0, 0, width, height).data;
        } catch (e) {
            // Fallback to text over image if cross-origin security rules block pixel access
            return drawOverlay(ctx, originalImg, textQuery, parsedFontSize, fontColor, width, height);
        }

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

        ctx.font = `bold ${parsedFontSize}px monospace`;
        ctx.textBaseline = "top";

        const textLen = textQuery.length;
        if (textLen === 0) {
            ctx.drawImage(originalImg, 0, 0);
            return canvas;
        }

        // Monospace measurement gives predictable uniform grid steps
        const charWidth = ctx.measureText("M").width;
        let charIndex = 0;

        // Render the image typographically
        for (let y = 0; y < height; y += parsedFontSize) {
            for (let x = 0; x < width; x += charWidth) {
                const px = Math.floor(x + charWidth / 2);
                const py = Math.floor(y + parsedFontSize / 2);

                if (px >= width || py >= height) continue;

                const index = (py * width + px) * 4;
                const r = imageData[index];
                const g = imageData[index + 1];
                const b = imageData[index + 2];
                const a = imageData[index + 3];

                // If pixel has visibility, draw the next character matching pixel color
                if (a > 10) {
                    const char = textQuery[charIndex % textLen];
                    ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a / 255})`;
                    ctx.fillText(char, x, y);
                    charIndex++;
                }
            }
            // Add slight shifting effect on every line
            charIndex++;
        }
    } else {
        // Overlay standard approach
        drawOverlay(ctx, originalImg, textQuery, parsedFontSize, fontColor, width, height);
    }

    return canvas;

    // Helper to draw conventional overlaid and automatically wrapped text on the image
    function drawOverlay(ctx, img, text, size, color, w, h) {
        ctx.drawImage(img, 0, 0, w, h);
        if (!text || text.length === 0) return canvas;

        ctx.fillStyle = color;
        ctx.font = `bold ${size}px sans-serif`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        // Add a high-contrast shadow/border for immediate readability
        ctx.shadowColor = "rgba(0, 0, 0, 0.8)";
        ctx.shadowBlur = 4;
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;

        const maxWidth = w * 0.9;
        const words = text.split(' ');
        let line = '';
        const lines = [];

        // Word wrapper calculation
        for (let n = 0; n < words.length; n++) {
            const testLine = line + words[n] + ' ';
            const metrics = ctx.measureText(testLine);
            if (metrics.width > maxWidth && n > 0) {
                lines.push(line);
                line = words[n] + ' ';
            } else {
                line = testLine;
            }
        }
        lines.push(line);

        // Center on canvas
        const lineHeight = size * 1.2;
        const totalHeight = lines.length * lineHeight;
        let startY = (h - totalHeight) / 2 + lineHeight / 2;

        for (let i = 0; i < lines.length; i++) {
            ctx.fillText(lines[i].trim(), w / 2, startY + i * lineHeight);
        }
        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

This tool allows users to transform an image using custom text queries through two distinct methods: typography mode and overlay mode. In typography mode, the tool recreates the visual essence of an image by tiling characters from a provided text string, using their colors and placement to mimic the original picture’s patterns and details. In overlay mode, the tool adds centered, wrapped text directly onto the image with a high-contrast shadow for improved readability. This tool is useful for creating stylized digital art, generating unique typographic portraits, or adding clear, legible captions and watermarks to photos for social media and graphic design projects.

Leave a Reply

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