Please bookmark this page to avoid losing your image tool!

Image Language Identifier And Translator

(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, defaultOcrLang = "eng", targetLang = "en") {
    // Create the main container
    const container = document.createElement('div');
    container.style.fontFamily = "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
    container.style.padding = "20px";
    container.style.maxWidth = "800px";
    container.style.margin = "0 auto";
    container.style.backgroundColor = "#fafafa";
    container.style.border = "1px solid #e0e0e0";
    container.style.borderRadius = "10px";
    container.style.boxShadow = "0 4px 6px rgba(0,0,0,0.05)";

    // Title
    const title = document.createElement('h2');
    title.innerText = "Image Language Identifier & Translator";
    title.style.marginTop = "0";
    title.style.color = "#333";
    title.style.textAlign = "center";
    container.appendChild(title);

    // Canvas to hold the extracted image
    const canvas = document.createElement('canvas');
    canvas.style.maxWidth = "100%";
    canvas.style.maxHeight = "400px";
    canvas.style.display = "block";
    canvas.style.margin = "0 auto 20px auto";
    canvas.style.borderRadius = "5px";
    canvas.style.border = "1px solid #ccc";
    
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    ctx.drawImage(originalImg, 0, 0);
    container.appendChild(canvas);

    // Status / Loading Area
    const statusArea = document.createElement('div');
    statusArea.style.marginBottom = "20px";
    statusArea.style.padding = "15px";
    statusArea.style.fontWeight = "bold";
    statusArea.style.color = "#0056b3";
    statusArea.style.backgroundColor = "#e7f1ff";
    statusArea.style.border = "1px solid #b6d4fe";
    statusArea.style.borderRadius = "5px";
    statusArea.style.textAlign = "center";
    statusArea.innerText = "Initializing processing engine...";
    container.appendChild(statusArea);

    // Results Area (Hidden Initially)
    const resultArea = document.createElement('div');
    resultArea.style.display = "none";
    
    const preStyle = "white-space: pre-wrap; word-wrap: break-word; background: #fff; padding: 12px; border: 1px solid #ddd; border-radius: 6px; max-height: 250px; overflow-y: auto; font-family: monospace; font-size: 14px; margin-top: 8px; color: #333;";
    
    resultArea.innerHTML = `
        <div style="margin-bottom: 20px;">
            <strong style="color: #444;">Extracted Text:</strong>
            <div id="extracted-text" style="${preStyle}"></div>
        </div>
        <div style="margin-bottom: 20px; background: #eefee8; padding: 15px; border: 1px solid #c3e6cb; border-radius: 6px;">
            <strong style="color: #155724; font-size: 16px;">Detected Language: </strong>
            <span id="detected-lang" style="font-weight: bold; color: #155724; font-size: 16px;"></span>
        </div>
        <div>
            <strong style="color: #444;">Translated Text (to ${targetLang}):</strong>
            <div id="translated-text" style="${preStyle}"></div>
        </div>
    `;
    container.appendChild(resultArea);

    const langNames = {
        "af": "Afrikaans", "sq": "Albanian", "am": "Amharic", "ar": "Arabic", "hy": "Armenian", "az": "Azerbaijani", 
        "eu": "Basque", "be": "Belarusian", "bn": "Bengali", "bs": "Bosnian", "bg": "Bulgarian", "ca": "Catalan", 
        "ceb": "Cebuano", "ny": "Chichewa", "zh-CN": "Chinese (Simplified)", "zh-TW": "Chinese (Traditional)", 
        "co": "Corsican", "hr": "Croatian", "cs": "Czech", "da": "Danish", "nl": "Dutch", "en": "English", 
        "eo": "Esperanto", "et": "Estonian", "tl": "Filipino", "fi": "Finnish", "fr": "French", "fy": "Frisian", 
        "gl": "Galician", "ka": "Georgian", "de": "German", "el": "Greek", "gu": "Gujarati", "ht": "Haitian Creole", 
        "ha": "Hausa", "haw": "Hawaiian", "iw": "Hebrew", "hi": "Hindi", "hmn": "Hmong", "hu": "Hungarian", 
        "is": "Icelandic", "ig": "Igbo", "id": "Indonesian", "ga": "Irish", "it": "Italian", "ja": "Japanese", 
        "jw": "Javanese", "kn": "Kannada", "kk": "Kazakh", "km": "Khmer", "ko": "Korean", "ku": "Kurdish (Kurmanji)", 
        "ky": "Kyrgyz", "lo": "Lao", "la": "Latin", "lv": "Latvian", "lt": "Lithuanian", "lb": "Luxembourgish", 
        "mk": "Macedonian", "mg": "Malagasy", "ms": "Malay", "ml": "Malayalam", "mt": "Maltese", "mi": "Maori", 
        "mr": "Marathi", "mn": "Mongolian", "my": "Myanmar (Burmese)", "ne": "Nepali", "no": "Norwegian", 
        "ps": "Pashto", "fa": "Persian", "pl": "Polish", "pt": "Portuguese", "pa": "Punjabi", "ro": "Romanian", 
        "ru": "Russian", "sm": "Samoan", "gd": "Scots Gaelic", "sr": "Serbian", "st": "Sesotho", "sn": "Shona", 
        "sd": "Sindhi", "si": "Sinhala", "sk": "Slovak", "sl": "Slovenian", "so": "Somali", "es": "Spanish", 
        "su": "Sundanese", "sw": "Swahili", "sv": "Swedish", "tg": "Tajik", "ta": "Tamil", "te": "Telugu", 
        "th": "Thai", "tr": "Turkish", "uk": "Ukrainian", "ur": "Urdu", "uz": "Uzbek", "vi": "Vietnamese", 
        "cy": "Welsh", "xh": "Xhosa", "yi": "Yiddish", "yo": "Yoruba", "zu": "Zulu"
    };

    // Process logic asynchronously to not block UI thread
    (async () => {
        try {
            // Dynamically load Tesseract.js if not available
            if (!window.Tesseract) {
                statusArea.innerText = "Loading Tesseract.js Engine...";
                await new Promise((resolve, reject) => {
                    const script = document.createElement('script');
                    script.src = "https://unpkg.com/tesseract.js@4.1.4/dist/tesseract.min.js";
                    script.onload = resolve;
                    script.onerror = () => reject(new Error("Failed to load Tesseract.js"));
                    document.head.appendChild(script);
                });
            }

            let recognizeLang = defaultOcrLang;
            let detectWorker = null;

            // Step 1: Detect Orientation and Script to select proper OCR language map automatically
            try {
                detectWorker = await Tesseract.createWorker({ 
                    logger: m => {
                        if(m.status === "loading tesseract core" || m.status.includes("osd")) {
                            statusArea.innerText = `Preparing Script Detection: ${m.status}...`;
                        }
                    } 
                });
                await detectWorker.loadLanguage('osd');
                await detectWorker.initialize('osd');
                
                statusArea.innerText = "Analyzing script on the image...";
                const detectResult = await detectWorker.detect(canvas);
                const scriptType = detectResult?.data?.script;
                
                // Map common OCR scripts to appropriate language bundles
                const scriptMap = {
                    'Latin': 'eng+spa+fra+deu+ita+por', // Includes accents
                    'Cyrillic': 'rus+ukr+bel',
                    'Han': 'chi_sim+chi_tra',
                    'Japanese': 'jpn',
                    'Hangul': 'kor',
                    'Arabic': 'ara',
                    'Hebrew': 'heb',
                    'Thai': 'tha',
                    'Devanagari': 'hin'
                };

                if (scriptType && scriptMap[scriptType]) {
                    recognizeLang = scriptMap[scriptType];
                }
            } catch (err) {
                console.warn("OSD Script detection skipped or failed. Falling back to default languages.", err);
            } finally {
                if (detectWorker) await detectWorker.terminate();
            }

            // Step 2: Optical Character Recognition (OCR) extraction
            const worker = await Tesseract.createWorker({
                logger: m => {
                    if (m.status === 'recognizing text') {
                        statusArea.innerText = `Extracting Text: ${Math.round(m.progress * 100)}%`;
                    } else {
                        statusArea.innerText = `Loading OCR language models (${recognizeLang})...`;
                    }
                }
            });

            await worker.loadLanguage(recognizeLang);
            await worker.initialize(recognizeLang);
            
            statusArea.innerText = "Extracting text contents...";
            const { data: { text } } = await worker.recognize(canvas);
            await worker.terminate();

            const extractedText = text.trim();
            if (!extractedText) {
                statusArea.innerText = "Process Complete: No text could be found on the image.";
                statusArea.style.backgroundColor = "#fff3cd";
                statusArea.style.color = "#856404";
                statusArea.style.borderColor = "#ffeeba";
                return;
            }

            // Step 3: Identify Language & Translate via unofficially free Google Translate API
            statusArea.innerText = "Identifying language and translating...";
            
            // Using POST to handle large bodies of extracted text securely inside API limits
            const gtUrl = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${targetLang}&dt=t`;
            const response = await fetch(gtUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: `q=${encodeURIComponent(extractedText)}`
            });
            
            if (!response.ok) throw new Error("Translation API encountered an error.");
            
            const json = await response.json();
            
            let translatedText = "";
            if (json[0]) {
                json[0].forEach(part => {
                    if (part[0]) translatedText += part[0];
                });
            }
            
            const detectedCode = json[2] || "Unknown";
            const humanReadableLang = langNames[detectedCode] ? `${langNames[detectedCode]} (${detectedCode})` : detectedCode;

            // Final Update: Reveal Results
            statusArea.style.display = "none";
            resultArea.style.display = "block";

            resultArea.querySelector('#extracted-text').innerText = extractedText;
            resultArea.querySelector('#detected-lang').innerText = humanReadableLang;
            resultArea.querySelector('#translated-text').innerText = translatedText;

        } catch (error) {
            console.error("Processing Error:", error);
            statusArea.innerText = "An error occurred: " + error.message;
            statusArea.style.backgroundColor = "#f8d7da";
            statusArea.style.color = "#721c24";
            statusArea.style.borderColor = "#f5c6cb";
        }
    })();

    return container;
}

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 allows you to extract text from images, identify the language of that text, and translate it into a target language. By utilizing Optical Character Recognition (OCR), it can recognize various scripts and characters within a picture. This is useful for translating documents, signs, menus, or any text-based images when you encounter a language you do not understand.

Leave a Reply

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