Please bookmark this page to avoid losing your image tool!

Image Translator 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.
/**
 * Translates text within an image by performing OCR, translating the text,
 * and redrawing the translated text over the original.
 *
 * @param {HTMLImageElement} originalImg The source image object.
 * @param {string} [sourceLang='ru'] The 2-letter ISO 639-1 code for the source language (e.g., 'en', 'ru', 'es').
 * @param {string} [targetLang='uk'] The 2-letter ISO 639-1 code for the target language (e.g., 'en', 'uk', 'fr').
 * @param {string} [backgroundColor='#FFFFFF'] The color to use for the background behind the translated text, in CSS format.
 * @param {string} [textColor='#000000'] The color of the translated text, in CSS format.
 * @returns {Promise<HTMLCanvasElement>} A canvas element with the translated image.
 */
async function processImage(originalImg, sourceLang = 'ru', targetLang = 'uk', backgroundColor = '#FFFFFF', textColor = '#000000') {

    // Helper function to dynamically load a script if it's not already present.
    const loadScript = (src) => {
        return new Promise((resolve, reject) => {
            // Check if script already exists
            if (document.querySelector(`script[src="${src}"]`)) {
                resolve();
                return;
            }
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Script load error for ${src}`));
            document.head.appendChild(script);
        });
    };

    // Maps 2-letter language codes to Tesseract's 3-letter codes.
    const getTesseractLangCode = (lang) => {
        const map = {
            'en': 'eng', 'ru': 'rus', 'uk': 'ukr', 'de': 'deu', 'fr': 'fra',
            'es': 'spa', 'it': 'ita', 'pt': 'por', 'pl': 'pol', 'ja': 'jpn',
            'ko': 'kor', 'zh': 'chi_sim', 'ar': 'ara', 'tr': 'tur'
        };
        return map[lang.toLowerCase()] || 'eng'; // Default to English if not found
    };

    try {
        // Step 1: Dynamically load the Tesseract.js library from a CDN
        await loadScript('https://cdn.jsdelivr.net/npm/tesseract.js@5.0.4/dist/tesseract.min.js');

        // Step 2: Set up the canvas
        const canvas = document.createElement('canvas');
        canvas.width = originalImg.naturalWidth;
        canvas.height = originalImg.naturalHeight;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(originalImg, 0, 0);

        // Step 3: Perform OCR on the image to detect text
        const tesseractLang = getTesseractLangCode(sourceLang);
        const { createWorker } = Tesseract;
        const worker = await createWorker();
        await worker.loadLanguage(tesseractLang);
        await worker.initialize(tesseractLang);
        const { data: { paragraphs } } = await worker.recognize(canvas);

        // Step 4: Process each detected paragraph of text
        for (const p of paragraphs) {
            if (!p.text.trim()) continue; // Skip empty text blocks

            // Step 4a: Translate the detected text using a free API
            const query = encodeURIComponent(p.text.trim());
            const url = `https://api.mymemory.translated.net/get?q=${query}&langpair=${sourceLang}|${targetLang}`;
            let translatedText = '[Translation Failed]';
            try {
                const response = await fetch(url);
                if (!response.ok) throw new Error(`API Error: ${response.statusText}`);
                const data = await response.json();
                if (data.responseStatus === 200) {
                    translatedText = data.responseData.translatedText;
                } else {
                     translatedText = `[Error: ${data.responseDetails}]`;
                }
            } catch (apiError) {
                console.error('Translation API error:', apiError);
                translatedText = '[API Error]';
            }

            // Step 4b: Redraw the text area on the canvas
            const bbox = p.bbox;

            // Erase the original text by drawing a solid rectangle
            ctx.fillStyle = backgroundColor;
            ctx.fillRect(bbox.x0, bbox.y0, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0);

            // Draw the translated text, adjusting font size and wrapping to fit
            ctx.fillStyle = textColor;
            ctx.textBaseline = 'top';
            ctx.textAlign = 'left';

            // Start with a font size based on the box height and shrink until it fits
            let fontSize = (bbox.y1 - bbox.y0);
            const boxWidth = bbox.x1 - bbox.x0 - 4; // Add a small margin
            const boxHeight = bbox.y1 - bbox.y0;
            let lines = [];
            
            // This loop adjusts font size and word-wraps the text to fit the box
            while (fontSize > 5) {
                ctx.font = `normal ${fontSize}px 'Arial', sans-serif`;
                const words = translatedText.split(' ');
                let currentLine = '';
                lines = [];

                for (const word of words) {
                    const testLine = currentLine.length === 0 ? word : `${currentLine} ${word}`;
                    const metrics = ctx.measureText(testLine);
                    if (metrics.width > boxWidth && currentLine.length > 0) {
                        lines.push(currentLine);
                        currentLine = word;
                    } else {
                        currentLine = testLine;
                    }
                }
                lines.push(currentLine);

                // Check if the wrapped text fits vertically
                if (lines.length * fontSize * 1.2 <= boxHeight) {
                    break; // Font size is good
                }
                fontSize -= 1; // Decrease font size and try again
            }

            // Calculate starting position for vertically centered text
            const lineHeight = fontSize * 1.2;
            const totalTextHeight = lines.length * lineHeight;
            let y = bbox.y0 + (boxHeight - totalTextHeight) / 2;

            // Draw each line of the wrapped text
            for (const line of lines) {
                // Horizontally center each line
                const textWidth = ctx.measureText(line).width;
                const x = bbox.x0 + (boxWidth - textWidth) / 2;
                ctx.fillText(line.trim(), x, y);
                y += lineHeight;
            }
        }

        // Clean up the Tesseract worker
        await worker.terminate();
        return canvas;

    } catch (error) {
        console.error("Error in processImage:", error);
        // On error, return the original image drawn on a canvas with an error message
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = originalImg.naturalWidth;
        errorCanvas.height = originalImg.naturalHeight;
        const errCtx = errorCanvas.getContext('2d');
        errCtx.drawImage(originalImg, 0, 0);
        errCtx.fillStyle = 'rgba(200, 0, 0, 0.8)';
        errCtx.fillRect(0, errorCanvas.height - 30, errorCanvas.width, 30);
        errCtx.fillStyle = 'white';
        errCtx.font = '16px Arial';
        errCtx.textAlign = 'center';
        errCtx.textBaseline = 'middle';
        errCtx.fillText(`An error occurred: ${error.message}`, errorCanvas.width / 2, errorCanvas.height - 15);
        return errorCanvas;
    }
}

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 Translator Generator is a powerful tool that enables users to translate text within images. By utilizing Optical Character Recognition (OCR), the tool identifies text in an image, translates it into a specified target language, and then redraws the translated text over the original image. This feature is particularly useful for translating foreign language content found in photos, documents, or screen captures, making it ideal for travelers, students, and professionals who need to understand text in different languages. Users can also customize the appearance of the translated text by selecting background and text colors, allowing for better integration with the original image.

Leave a Reply

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