Please bookmark this page to avoid losing your image tool!

Image To Two Verse Text Generator

(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, 
    verse1 = "В тайном танце света тень Начинает новый день, Мир проснулся в тишине, Отражаясь как во сне.", 
    verse2 = "Краски смело льют поток, Заполняя каждый слог, И вплетаются слова В этот образ навсегда.", 
    fontSize = 10, 
    backgroundColor = "#000000"
) {
    // Determine maximum safe width to avoid huge load times for giant images
    const maxWidth = 1200;
    let width = originalImg.naturalWidth || originalImg.width;
    let height = originalImg.naturalHeight || originalImg.height;

    // Scale dynamically if necessary while preserving aspect ratio
    if (width > maxWidth) {
        const scale = maxWidth / width;
        width = maxWidth;
        height = Math.floor(height * scale);
    }

    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Create a hidden canvas to extract pixel colors from the original image
    const offscreen = document.createElement('canvas');
    offscreen.width = width;
    offscreen.height = height;
    const offCtx = offscreen.getContext('2d', { willReadFrequently: true });
    offCtx.drawImage(originalImg, 0, 0, width, height);

    let imgData;
    try {
        imgData = offCtx.getImageData(0, 0, width, height).data;
    } catch (e) {
        // Fallback for CORS (Cross-Origin Resource Sharing) restrictions on canvases
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(0, 0, width, height);
        ctx.fillStyle = "#ff0000";
        ctx.font = "20px sans-serif";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText("Error: Cross-Origin Image data cannot be read.", width / 2, height / 2);
        return canvas;
    }

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

    // Prepare repeating text strings by cleaning up line breaks and excess spaces
    let v1Text = verse1.replace(/\n|\r/g, ' ').replace(/\s+/g, ' ').trim() + ' ';
    let v2Text = verse2.replace(/\n|\r/g, ' ').replace(/\s+/g, ' ').trim() + ' ';

    if (!v1Text.trim()) v1Text = "Verse 1 ";
    if (!v2Text.trim()) v2Text = "Verse 2 ";

    // Set typography rules
    const fSize = Number(fontSize) || 10;
    ctx.font = `bold ${fSize}px monospace`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // Calculate grid increments based on text dimensions
    const stepX = ctx.measureText("M").width || (fSize * 0.6);
    const stepY = fSize; 

    let tIndex1 = 0;
    let tIndex2 = 0;

    // Iterate through image canvas in a grid layout plotting colored text
    for (let y = stepY / 2; y < height; y += stepY) {
        for (let x = stepX / 2; x < width; x += stepX) {
            const px = Math.floor(x);
            const py = Math.floor(y);
            
            // Map coordinates directly to RGBA pixel array indices
            const index = (py * width + px) * 4;
            const r = imgData[index];
            const g = imgData[index + 1];
            const b = imgData[index + 2];
            const a = imgData[index + 3];

            // Render characters if opacity corresponds to visible pixels
            if (a > 0) {
                // Apply the corresponding color of the image's pixel to the character
                ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a / 255})`;
                let char;
                
                // Top half of image logic goes to Verse 1, bottom logic goes to Verse 2
                if (y <= height / 2) {
                    char = v1Text[tIndex1 % v1Text.length];
                    tIndex1++;
                } else {
                    char = v2Text[tIndex2 % v2Text.length];
                    tIndex2++;
                }
                
                // Plot single character
                ctx.fillText(char, x, y);
            }
        }
    }

    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 transforms an image into a unique typographic artwork by recreating the image using text. It works by analyzing the colors and opacity of an uploaded image and replacing pixels with characters from two custom verses of text. The top half of the image is rendered using the first verse, while the bottom half uses the second verse, with each character inheriting the color of its corresponding pixel location. This tool is ideal for creating artistic portraits, poetic visual compositions, or stylized digital assets for social media and creative design projects.

Leave a Reply

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