Please bookmark this page to avoid losing your image tool!

Photo Text Language Translator Creator

(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 = 'auto') {
    /**
     * Dynamically loads a script into the document.
     * @param {string} url The URL of the script to load.
     * @returns {Promise<void>} A promise that resolves when the script has loaded.
     */
    const loadScript = (url) => {
        return new Promise((resolve, reject) => {
            // Check if the script is already on the page
            if (document.querySelector(`script[src="${url}"]`)) {
                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);
        });
    };

    // 1. Create a canvas and draw the original image onto it.
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    ctx.drawImage(originalImg, 0, 0);

    // 2. Load the Tesseract.js library from a CDN.
    try {
        await loadScript('https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js');
    } catch (error) {
        console.error("Failed to load Tesseract.js:", error);
        ctx.fillStyle = 'red';
        ctx.font = '20px sans-serif';
        ctx.fillText('Error: Could not load OCR library.', 20, 40);
        return canvas;
    }

    // 3. Initialize the Tesseract worker and perform OCR.
    const { Tesseract } = window;
    // Loading common languages for better script detection. This may be slow on the first run.
    const worker = await Tesseract.createWorker('eng+fra+deu+spa+jpn+chi_sim', 1, {
        logger: m => console.log(m.status, `${Math.round(m.progress * 100)}%`) // Optional: Log progress
    });

    let recognitionResult;
    try {
        recognitionResult = await worker.recognize(canvas);
    } catch (error) {
        console.error("OCR process failed:", error);
        ctx.fillStyle = 'red';
        ctx.font = '20px sans-serif';
        ctx.fillText('Error: OCR failed.', 20, 40);
        await worker.terminate();
        return canvas;
    }

    const { data: { lines } } = recognitionResult;

    if (!lines || lines.length === 0) {
        console.log("No text found in the image.");
        await worker.terminate();
        return canvas;
    }

    // 4. Create translation tasks for each detected line of text.
    const translationPromises = lines.map(line => {
        const textToTranslate = line.text.trim();
        if (!textToTranslate) return Promise.resolve(null);

        // Uses a free, public, no-key translation API (MyMemory)
        const langPair = `${sourceLang}|${targetLang}`;
        const apiUrl = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(textToTranslate)}&langpair=${langPair}`;

        return fetch(apiUrl)
            .then(response => {
                if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
                return response.json();
            })
            .then(data => ({
                // Fallback to original text if translation fails
                translated: data.responseData?.translatedText || textToTranslate,
                bbox: line.bbox
            }))
            .catch(error => {
                console.error("Translation API error:", error);
                // On error, use the original text
                return {
                    translated: textToTranslate,
                    bbox: line.bbox
                };
            });
    });

    const translatedLines = (await Promise.all(translationPromises)).filter(Boolean);

    // 5. Draw the translated text over the original image.
    for (const line of translatedLines) {
        const { bbox, translated } = line;

        // a. Hide the original text by painting a rectangle over it.
        // The rectangle's color is sampled from the top-left corner of the text box for better blending.
        try {
            const pixelData = ctx.getImageData(bbox.x0, bbox.y0, 1, 1).data;
            ctx.fillStyle = `rgb(${pixelData[0]}, ${pixelData[1]}, ${pixelData[2]})`;
        } catch (e) {
            // Fallback color if getImageData fails (e.g., tainted canvas)
             ctx.fillStyle = 'white';
        }
        ctx.fillRect(bbox.x0, bbox.y0, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0);

        // b. Determine text color (black or white) for best contrast against the new background.
        const [r, g, b] = ctx.fillStyle.match(/\d+/g).map(Number);
        const luminance = (0.299 * r + 0.587 * g + 0.114 * b);
        ctx.fillStyle = luminance > 128 ? 'black' : 'white';

        // c. Dynamically adjust font size to fit the translated text into the original text's bounding box.
        let fontSize = bbox.y1 - bbox.y0; // Initial guess for font size
        ctx.font = `bold ${fontSize}px sans-serif`;

        while (ctx.measureText(translated).width > (bbox.x1 - bbox.x0) && fontSize > 8) {
            fontSize--;
            ctx.font = `bold ${fontSize}px sans-serif`;
        }
        
        // d. Draw the text, centered vertically in the bounding box.
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        const y_center = bbox.y0 + (bbox.y1 - bbox.y0) / 2;
        ctx.fillText(translated, bbox.x0, y_center);
    }

    // 6. Clean up the Tesseract worker to free up resources.
    await worker.terminate();

    // 7. Return the final canvas element.
    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 Photo Text Language Translator Creator is a web-based tool that processes images to extract text through Optical Character Recognition (OCR) and translates the extracted text into a chosen target language. This tool can be particularly useful for users who want to translate text from images, such as signs, documents, or screenshots. It supports automatic detection of the source language and can translate into multiple languages, making it an effective resource for travelers, language learners, or anyone in need of multilingual text translation from visual content.

Leave a Reply

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