Please bookmark this page to avoid losing your image tool!

Image Scanner Identifier And Language 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', defaultTransLang = 'es') {
    // Main Wrapper Container
    const container = document.createElement('div');
    container.style.fontFamily = 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
    container.style.maxWidth = '900px';
    container.style.margin = '0 auto';
    container.style.padding = '20px';
    container.style.boxSizing = 'border-box';
    container.style.backgroundColor = '#ffffff';
    container.style.borderRadius = '12px';
    container.style.boxShadow = '0 4px 15px rgba(0,0,0,0.08)';
    container.style.border = '1px solid #e0e0e0';

    // Header Title
    const title = document.createElement('h2');
    title.textContent = 'Image Scanner, Identifier & Translator';
    title.style.marginTop = '0';
    title.style.color = '#333';
    title.style.borderBottom = '2px solid #f0f0f0';
    title.style.paddingBottom = '10px';
    container.appendChild(title);

    // Control Panel
    const controls = document.createElement('div');
    controls.style.display = 'flex';
    controls.style.gap = '15px';
    controls.style.alignItems = 'center';
    controls.style.marginBottom = '20px';
    controls.style.flexWrap = 'wrap';
    
    // OCR Language Selector
    const ocrSelect = document.createElement('select');
    ocrSelect.style.padding = '8px';
    ocrSelect.style.borderRadius = '6px';
    ocrSelect.style.border = '1px solid #ccc';
    const tesseractLangs = {
        'eng': 'English', 'spa': 'Spanish', 'fra': 'French', 
        'deu': 'German', 'chi_sim': 'Chinese', 'jpn': 'Japanese', 'rus': 'Russian',
        'por': 'Portuguese', 'ita': 'Italian', 'kor': 'Korean', 'hin': 'Hindi'
    };
    for (const [code, name] of Object.entries(tesseractLangs)) {
        const option = document.createElement('option');
        option.value = code;
        option.textContent = name;
        if (code === defaultOcrLang) option.selected = true;
        ocrSelect.appendChild(option);
    }

    // Target Translator Language Selector
    const transSelect = document.createElement('select');
    transSelect.style.padding = '8px';
    transSelect.style.borderRadius = '6px';
    transSelect.style.border = '1px solid #ccc';
    const googleLangs = {
        'en': 'English', 'es': 'Spanish', 'fr': 'French', 
        'de': 'German', 'zh-CN': 'Chinese (Simp)', 'ja': 'Japanese', 'ru': 'Russian',
        'pt': 'Portuguese', 'it': 'Italian', 'ko': 'Korean', 'hi': 'Hindi', 'ar': 'Arabic'
    };
    for (const [code, name] of Object.entries(googleLangs)) {
        const option = document.createElement('option');
        option.value = code;
        option.textContent = name;
        if (code === defaultTransLang) option.selected = true;
        transSelect.appendChild(option);
    }

    // Action Button
    const runBtn = document.createElement('button');
    runBtn.textContent = 'Scan & Translate';
    runBtn.style.padding = '8px 20px';
    runBtn.style.backgroundColor = '#0070f3';
    runBtn.style.color = '#fff';
    runBtn.style.border = 'none';
    runBtn.style.borderRadius = '6px';
    runBtn.style.fontWeight = 'bold';
    runBtn.style.cursor = 'pointer';
    runBtn.style.boxShadow = '0 2px 4px rgba(0,112,243,0.3)';
    runBtn.onmouseover = () => runBtn.style.backgroundColor = '#0051b3';
    runBtn.onmouseout = () => runBtn.style.backgroundColor = '#0070f3';

    const createLabel = (text) => {
        const lbl = document.createElement('span');
        lbl.textContent = text;
        lbl.style.fontWeight = '500';
        lbl.style.color = '#555';
        lbl.style.fontSize = '14px';
        return lbl;
    };

    controls.appendChild(createLabel('Image Language:'));
    controls.appendChild(ocrSelect);
    controls.appendChild(createLabel('Translate to:'));
    controls.appendChild(transSelect);
    controls.appendChild(runBtn);
    container.appendChild(controls);

    // Image Display Canvas
    const imgWrapper = document.createElement('div');
    imgWrapper.style.marginBottom = '20px';
    imgWrapper.style.textAlign = 'center';
    imgWrapper.style.backgroundColor = '#f8f9fa';
    imgWrapper.style.padding = '10px';
    imgWrapper.style.borderRadius = '8px';
    imgWrapper.style.border = '1px dashed #ccc';
    
    const canvas = document.createElement('canvas');
    canvas.style.maxWidth = '100%';
    canvas.style.maxHeight = '400px';
    canvas.style.objectFit = 'contain';
    canvas.style.borderRadius = '4px';
    
    // Draw Original Image on Canvas
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    ctx.drawImage(originalImg, 0, 0);
    imgWrapper.appendChild(canvas);
    container.appendChild(imgWrapper);

    // Status / Progress Bar
    const statusBox = document.createElement('div');
    statusBox.style.padding = '12px 15px';
    statusBox.style.backgroundColor = '#e0f7fa';
    statusBox.style.color = '#006064';
    statusBox.style.borderRadius = '6px';
    statusBox.style.marginBottom = '20px';
    statusBox.style.fontWeight = 'bold';
    statusBox.style.fontSize = '14px';
    statusBox.style.display = 'flex';
    statusBox.style.alignItems = 'center';
    statusBox.textContent = 'Awaiting initialization...';
    container.appendChild(statusBox);

    // Text Areas for OCR and Translation
    const textContainer = document.createElement('div');
    textContainer.style.display = 'flex';
    textContainer.style.gap = '20px';
    textContainer.style.flexWrap = 'wrap';

    const createTextAreaBlock = (titleText, placeholder) => {
        const block = document.createElement('div');
        block.style.flex = '1';
        block.style.minWidth = '280px';
        block.style.display = 'flex';
        block.style.flexDirection = 'column';

        const label = document.createElement('label');
        label.textContent = titleText;
        label.style.fontWeight = '600';
        label.style.marginBottom = '8px';
        label.style.color = '#333';
        label.style.fontSize = '14px';

        const textarea = document.createElement('textarea');
        textarea.style.height = '180px';
        textarea.style.padding = '12px';
        textarea.style.border = '1px solid #dcdcdc';
        textarea.style.borderRadius = '6px';
        textarea.style.fontFamily = 'inherit';
        textarea.style.fontSize = '14px';
        textarea.style.lineHeight = '1.5';
        textarea.style.resize = 'vertical';
        textarea.style.backgroundColor = '#fafafa';
        textarea.placeholder = placeholder;

        block.appendChild(label);
        block.appendChild(textarea);
        return { block, textarea };
    };

    const sourceBlock = createTextAreaBlock('Extracted Text (Editable)', 'Image text will appear here...');
    const translatedBlock = createTextAreaBlock('Translated Result', 'Translation will appear here...');
    translatedBlock.textarea.readOnly = true;
    translatedBlock.textarea.style.backgroundColor = '#eef3fb';

    textContainer.appendChild(sourceBlock.block);
    textContainer.appendChild(translatedBlock.block);
    container.appendChild(textContainer);

    // Core Processing Functions
    const translateText = async () => {
        const text = sourceBlock.textarea.value.trim();
        if (!text) {
            translatedBlock.textarea.value = '';
            statusBox.textContent = 'Ready.';
            return;
        }
        
        statusBox.textContent = 'Translating...';
        statusBox.style.backgroundColor = '#fff3e0';
        statusBox.style.color = '#ef6c00';

        try {
            // Using a highly reliable cross-origin Google Translate client API endpoint
            const targetLang = transSelect.value;
            const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}`;
            const response = await fetch(url);
            const json = await response.json();
            
            let translated = '';
            if (json && json[0]) {
                for (let i = 0; i < json[0].length; i++) {
                    if (json[0][i][0]) translated += json[0][i][0];
                }
            }
            
            translatedBlock.textarea.value = translated;
            const detectedLang = json[2] ? json[2].toUpperCase() : 'AUTO';
            statusBox.style.backgroundColor = '#e8f5e9';
            statusBox.style.color = '#2e7d32';
            statusBox.textContent = `Completed! Detected input language: ${detectedLang}`;
        } catch (err) {
            console.error('Translation error:', err);
            statusBox.style.backgroundColor = '#ffebee';
            statusBox.style.color = '#c62828';
            statusBox.textContent = `Translation Error: ${err.message}`;
        }
    };

    // Make UI interactive: translating instantly when target language changes or when user edits OCR output manually
    transSelect.addEventListener('change', translateText);

    let typingTimer;
    sourceBlock.textarea.addEventListener('input', () => {
        clearTimeout(typingTimer);
        typingTimer = setTimeout(translateText, 700); // 700ms debounce
    });

    const loadTesseract = () => {
        return new Promise((resolve, reject) => {
            if (window.Tesseract) return resolve();
            
            let script = document.getElementById('tesseract-ocr-script');
            if (script) {
                // Script tag exists, wait for it to assign window.Tesseract
                const interval = setInterval(() => {
                    if (window.Tesseract) {
                        clearInterval(interval);
                        resolve();
                    }
                }, 100);
                return;
            }
            
            script = document.createElement('script');
            script.id = 'tesseract-ocr-script';
            script.src = 'https://unpkg.com/tesseract.js@5.0.3/dist/tesseract.min.js';
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    };

    const runFullProcess = async () => {
        runBtn.disabled = true;
        runBtn.style.opacity = '0.6';
        runBtn.style.cursor = 'not-allowed';
        const previousStatusColor = statusBox.style.color;
        const previousStatusBg = statusBox.style.backgroundColor;

        try {
            sourceBlock.textarea.value = '';
            translatedBlock.textarea.value = '';
            
            statusBox.style.backgroundColor = '#e3f2fd';
            statusBox.style.color = '#1565c0';
            statusBox.textContent = 'Loading OCR Engine (Tesseract.js)...';
            
            await loadTesseract();

            statusBox.textContent = 'Engine Loaded. Initializing Scan...';
            
            const selectedOcrLang = ocrSelect.value;
            const result = await window.Tesseract.recognize(originalImg, selectedOcrLang, {
                logger: m => {
                    if (m.status === 'recognizing text') {
                        const progress = Math.round(m.progress * 100);
                        statusBox.textContent = `Scanning Image... ${progress}%`;
                    } else if (m.status === 'loading language traineddata') {
                        statusBox.textContent = `Downloading ${selectedOcrLang} language components (${Math.round(m.progress * 100)}%)`;
                    } else {
                        statusBox.textContent = `Processing: ${m.status}`;
                    }
                }
            });

            const text = result.data.text;
            sourceBlock.textarea.value = text;

            if (!text.trim()) {
                statusBox.textContent = 'Finished. No discernible text found in the image.';
                statusBox.style.backgroundColor = '#fff3e0';
                statusBox.style.color = '#e65100';
                return;
            }

            // Once text is extracted, automatically translate it
            await translateText();

        } catch (err) {
            console.error('OCR Process failed:', err);
            statusBox.style.backgroundColor = '#ffebee';
            statusBox.style.color = '#c62828';
            statusBox.textContent = `Scanner Error: ${err.message}`;
        } finally {
            runBtn.disabled = false;
            runBtn.style.opacity = '1';
            runBtn.style.cursor = 'pointer';
        }
    };

    runBtn.addEventListener('click', runFullProcess);

    // Auto-run the scanner as soon as the component mounts
    setTimeout(runFullProcess, 100);

    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 users to extract text from images using Optical Character Recognition (OCR) and instantly translate that text into various languages. Users can select the source language of the image to improve scanning accuracy and choose a target language for translation. It is highly useful for travelers needing to read foreign signage, students translating documents from photos, or anyone needing to digitize and translate text contained within images.

Leave a Reply

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

Other Image Tools:

Movie Studio Name and Year Image Scanner Identifier

Image Based Audio Song Lyric Identifier and MP3 Downloader

Image Scanner Interface Address Identifier Tool

3D Printer Scanner Identifier Tool

3D Model Printer and Scanner Identifier Tool

Image Scanner City Identifier Tool

Image Scanner Movie Identifier Tool

Scanner Identifier for Studio Company and Year from Image

Image Scanner Language Identifier and Dub Translator Tool

Image Scanner Software and Mediateka Topic Search Identifier

Image Scanner Identifier and Mediateka Search Topic Picker

Image Scanner Identifier Picker

Mediateka Image Scanner and Identifier Tool

Image Based Movie Scanner and Identifier

Image Address Icon Generator Tool

Image Company Year Identifier Scanner Tool

AI Company Year Generator From Image

Movie Studio Of The Year Photo Remover

AI Studio Company Year Image Identifier Generator

Image Search For Film Studio Finders

Image Scanner Topic Search Tool for Movie Studios and Companies

Image Search Topic Identifier For Movie Studios Of The Year

Movie Studio and Film Production ID Converter

Movie Project Details Generator with Studio and Year Information

Movie Studio Year ID Scanner and Converter Tool

Company of the Year Studio Project Converter

Image Description Tool

Image Converter

Image URL To Web Address Converter

Website Address To Favicon Icon Converter

Image To Web Interface Website Address Database Icon Converter

Television Icon Generator

TV Icon Image Converter

TV Aspect Ratio Image Converter

Image URL To Database Converter

Image To PNG Converter

See All →