Please bookmark this page to avoid losing your image tool!

Image Text Translator With Import From Photo

(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, targetLang = 'en', sourceLang = 'en') {

    /**
     * Dynamically loads a script if it's not already on the page.
     * @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 (window.Tesseract) {
                return resolve();
            }
            if (document.querySelector(`script[src="${url}"]`)) {
                // If script tag exists, wait for it to load
                const script = document.querySelector(`script[src="${url}"]`);
                const initialOnload = script.onload;
                script.onload = () => {
                   if(initialOnload) initialOnload();
                   resolve();
                }
                const initialOnerror = script.onerror;
                 script.onerror = (err) => {
                   if(initialOnerror) initialOnerror(err);
                   reject(new Error(`Script load error for ${url}`));
                }
                return;
            }
            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);
        });
    };

    /**
     * Translates text using a public, non-official Google Translate API endpoint.
     * @param {string} text The text to translate.
     * @param {string} from The source language code (e.g., 'en', 'auto').
     * @param {string} to The target language code (e.g., 'es').
     * @returns {Promise<string>} The translated text.
     */
    const translateText = async (text, from, to) => {
        if (!text || text.trim() === '') return '';
        const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${from}&tl=${to}&dt=t&q=${encodeURIComponent(text)}`;
        try {
            const response = await fetch(url);
            if (!response.ok) {
                throw new Error(`Network response was not ok (${response.status})`);
            }
            const data = await response.json();
            if (data && data[0]) {
                return data[0].map(item => item[0]).join('');
            }
            return 'Translation format unknown.';
        } catch (error) {
            console.error('Translation failed:', error);
            return `Translation Error: Could not connect to the translation service.`;
        }
    };
    
    /**
     * Maps common 2-letter language codes to Tesseract's 3-letter codes.
     * @param {string} lang The 2-letter language code.
     * @returns {string} The corresponding 3-letter code for Tesseract.
     */
    const getTesseractLangCode = (lang) => {
        const map = {
            'en': 'eng', 'ru': 'rus', 'de': 'deu', 'fr': 'fra', 'es': 'spa',
            'it': 'ita', 'pt': 'por', 'ja': 'jpn', 'ko': 'kor', 'ar': 'ara',
            'hi': 'hin', 'zh-cn': 'chi_sim', 'zh-tw': 'chi_tra'
        };
        return map[lang.toLowerCase()] || 'eng'; // Default to English
    };

    /**
     * Wraps text to fit within a max width 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.
     * @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 lines = text.split('\n');
        for (const line of lines) {
            const words = line.split(' ');
            let currentLine = '';
            for (let n = 0; n < words.length; n++) {
                const testLine = currentLine + words[n] + ' ';
                const metrics = context.measureText(testLine);
                const testWidth = metrics.width;
                if (testWidth > maxWidth && n > 0) {
                    context.fillText(currentLine, x, y);
                    currentLine = words[n] + ' ';
                    y += lineHeight;
                } else {
                    currentLine = testLine;
                }
            }
            context.fillText(currentLine, x, y);
            y += lineHeight;
        }
    };

    // Prepare output canvas
    const TEXT_AREA_HEIGHT = 150;
    const PADDING = 20;

    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width < 400 ? 400 : originalImg.width;
    canvas.height = originalImg.height + TEXT_AREA_HEIGHT;
    const ctx = canvas.getContext('2d');

    // Draw background and image
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(originalImg, 0, 0);

    // Draw a separator
    ctx.strokeStyle = '#cccccc';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(0, originalImg.height);
    ctx.lineTo(canvas.width, originalImg.height);
    ctx.stroke();

    /**
     * Helper to draw status updates in the text area of the canvas.
     * @param {string} message The message to display.
     */
    const drawStatus = (message) => {
        ctx.fillStyle = '#ffffff';
        ctx.fillRect(0, originalImg.height + 1, canvas.width, TEXT_AREA_HEIGHT - 1);
        ctx.fillStyle = '#333333';
        ctx.font = '16px Arial';
        ctx.textAlign = 'center';
        ctx.fillText(message, canvas.width / 2, originalImg.height + TEXT_AREA_HEIGHT / 2);
    };

    try {
        drawStatus('Loading OCR engine...');
        await loadScript('https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js');
        
        const worker = await Tesseract.createWorker({
            logger: m => {
                if (m.status === 'recognizing text') {
                    drawStatus(`Recognizing Text: ${Math.round(m.progress * 100)}%`);
                } else if (m.status.includes('loading language')) {
                    drawStatus('Loading language model...');
                }
            }
        });

        const tesseractLang = getTesseractLangCode(sourceLang);
        await worker.loadLanguage(tesseractLang);
        await worker.initialize(tesseractLang);
        
        drawStatus('Recognizing Text: 0%');
        const { data: { text: extractedText } } = await worker.recognize(originalImg);
        await worker.terminate();

        if (!extractedText || extractedText.trim() === '') {
            drawStatus('No text found in the image.');
            return canvas;
        }
        
        drawStatus('Translating text...');
        const translatedText = await translateText(extractedText, sourceLang, targetLang);
        
        // Clear status and draw final result
        ctx.fillStyle = '#ffffff';
        ctx.fillRect(0, originalImg.height + 1, canvas.width, TEXT_AREA_HEIGHT - 1);

        ctx.textAlign = 'left';
        ctx.fillStyle = '#000000';
        
        const lineHeight = 22;
        const startY = originalImg.height + PADDING + lineHeight/2;
        const maxWidth = canvas.width - (PADDING * 2);

        ctx.font = `bold 16px Arial`;
        ctx.fillText(`Translated Text (${targetLang.toUpperCase()}):`, PADDING, startY);
        
        ctx.font = `16px Arial`;
        wrapText(ctx, translatedText, PADDING, startY + lineHeight, maxWidth, lineHeight);

        return canvas;

    } catch (error) {
        console.error('An error occurred during image processing:', error);
        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 Translator With Import From Photo tool allows users to upload an image and extract text from it using Optical Character Recognition (OCR). After extracting the text, the tool can translate it into a target language of your choice. This utility is particularly useful for translating documents, signs, or any text present in images, making it a great asset for travelers, students, or professionals working with multilingual texts. The tool supports multiple languages, allowing for seamless communication across language barriers.

Leave a Reply

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