Please bookmark this page to avoid losing your image tool!

Image Text Translation Tool

(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.
async function processImage(originalImg, sourceLang = 'en', targetLang = 'ru') {
    /**
     * Helper function to dynamically load an external script.
     * It ensures the script is loaded only once.
     * @param {string} url - The URL of the script to load.
     * @returns {Promise<void>} - A promise that resolves when the script is loaded.
     */
    const loadScript = (url) => {
        return new Promise((resolve, reject) => {
            // If the script's global object already exists, resolve immediately.
            if (window.Tesseract) {
                return resolve();
            }
            const script = document.createElement('script');
            script.src = url;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Script load error for ${url}`));
            document.head.appendChild(script);
        });
    };

    /**
     * Helper function to wrap and draw text on a canvas.
     * @param {CanvasRenderingContext2D} context - The canvas rendering context.
     * @param {string} text - The text to wrap.
     * @param {number} x - The starting x-coordinate.
     * @param {number} y - The starting y-coordinate for the first line.
     * @param {number} maxWidth - The maximum width of a line.
     * @param {number} lineHeight - The height of each line.
     */
    const wrapText = (context, text, x, y, maxWidth, lineHeight) => {
        const words = text.split(' ');
        let line = '';
        let initialY = y;

        for (let n = 0; n < words.length; n++) {
            // Check if drawing another line would go outside the overlay
            if (y > (initialY + context.canvas.height - lineHeight * 2)) {
                context.fillText(line.trim() + '...', x, y);
                return;
            }
            
            const testLine = line + words[n] + ' ';
            const metrics = context.measureText(testLine);
            const testWidth = metrics.width;

            if (testWidth > maxWidth && n > 0) {
                context.fillText(line.trim(), x, y);
                line = words[n] + ' ';
                y += lineHeight;
            } else {
                line = testLine;
            }
        }
        context.fillText(line.trim(), x, y);
    };

    // Initialize the output canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    /**
     * Helper to draw status messages directly onto the canvas.
     * @param {string} text - The status message to display.
     */
    const drawStatus = (text) => {
        ctx.drawImage(originalImg, 0, 0); // Redraw background image
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(0, canvas.height / 2 - 30, canvas.width, 60);
        ctx.fillStyle = 'white';
        ctx.textAlign = 'center';
        ctx.font = `bold ${Math.min(24, canvas.width / 15)}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
        ctx.fillText(text, canvas.width / 2, canvas.height / 2 + 8);
    };

    try {
        drawStatus('Initializing...');
        
        // Asynchronously load the Tesseract.js OCR library from a CDN
        await loadScript('https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js');

        // Map standard 2-letter language codes to the 3-letter codes Tesseract uses
        const langMap = { 'en': 'eng', 'ru': 'rus', 'de': 'deu', 'fr': 'fra', 'es': 'spa', 'it': 'ita', 'ja': 'jpn', 'zh': 'chi_sim' };
        const tesseractLang = langMap[sourceLang] || 'eng'; // Default to English if mapping not found

        // Create a Tesseract worker to perform OCR, with a logger for progress updates
        drawStatus('Loading OCR Model...');
        const worker = await Tesseract.createWorker(tesseractLang, 1, {
            logger: m => {
                if (m.status === 'recognizing text') {
                    const progress = (m.progress * 100).toFixed(0);
                    drawStatus(`Recognizing Text... ${progress}%`);
                }
            }
        });

        const { data: { text } } = await worker.recognize(originalImg);
        await worker.terminate(); // Terminate worker to free up resources

        if (!text || text.trim() === '') {
            drawStatus('No text found.');
            return canvas;
        }

        // Translate the extracted text using a free, no-key-required translation API
        drawStatus('Translating Text...');
        const apiUrl = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(text)}&langpair=${sourceLang}|${targetLang}`;
        const response = await fetch(apiUrl);
        if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
        
        const translationData = await response.json();
        const translatedText = translationData.responseData.translatedText;

        // Draw the final result on the canvas
        ctx.drawImage(originalImg, 0, 0);

        const overlayHeight = Math.min(originalImg.naturalHeight * 0.35, 200);
        const overlayY = originalImg.naturalHeight - overlayHeight;

        ctx.fillStyle = 'rgba(0, 0, 0, 0.75)'; // Semi-transparent black overlay
        ctx.fillRect(0, overlayY, originalImg.naturalWidth, overlayHeight);

        ctx.fillStyle = 'white';
        ctx.textAlign = 'left';
        const padding = 15;
        const fontSize = Math.max(14, Math.min(24, overlayHeight / 5));
        ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
        const lineHeight = fontSize * 1.3;
        const startX = padding;
        const startY = overlayY + padding + fontSize;
        const maxWidth = originalImg.naturalWidth - (padding * 2);
        
        wrapText(ctx, translatedText, startX, startY, maxWidth, lineHeight);

    } catch (error) {
        console.error('Image translation failed:', error);
        ctx.drawImage(originalImg, 0, 0);
        drawStatus(`Error: ${error.message}`);
    }
    
    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 Translation Tool allows users to extract text from images and translate it into a different language. By utilizing optical character recognition (OCR) technology, this tool can identify text present in images and convert it into a translatable format. It supports translation between various languages, making it useful for users needing to understand foreign language content found in documents, signs, or images. This tool is particularly helpful for travelers, educators, and anyone requiring quick translations of visual text, enabling seamless communication across language barriers.

Leave a Reply

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