Please bookmark this page to avoid losing your image tool!

Image Finder 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.
async function processImage(originalImg, sourceLang = 'eng', targetLang = 'rus') {
    /**
     * Dynamically loads the Tesseract.js script from a CDN.
     * @returns {Promise<void>} A promise that resolves when the script is loaded.
     */
    const loadTesseract = () => {
        return new Promise((resolve, reject) => {
            if (window.Tesseract) {
                return resolve();
            }
            const script = document.createElement('script');
            script.src = 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js';
            script.onload = () => resolve();
            script.onerror = (err) => reject(new Error('Failed to load Tesseract.js script.'));
            document.head.appendChild(script);
        });
    };

    /**
     * Maps Tesseract language codes (ISO 639-2/3) to API-friendly codes (ISO 639-1).
     * @param {string} tessLang - The Tesseract language code (e.g., 'eng', 'spa').
     * @returns {string} The corresponding ISO 639-1 code (e.g., 'en', 'es').
     */
    const getApiLangCode = (tessLang) => {
        const langMap = {
            'eng': 'en', 'rus': 'ru', 'spa': 'es', 'fra': 'fr', 'deu': 'de',
            'ita': 'it', 'jpn': 'ja', 'chi_sim': 'zh-CN', 'chi_tra': 'zh-TW',
            'kor': 'ko', 'por': 'pt', 'ara': 'ar', 'hin': 'hi'
        };
        const cleanedLang = tessLang.trim().toLowerCase();
        return langMap[cleanedLang] || cleanedLang.substring(0, 2);
    };

    // --- Main container and elements ---
    const container = document.createElement('div');
    container.style.fontFamily = 'Arial, sans-serif';
    container.style.textAlign = 'center';

    const canvas = document.createElement('canvas');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);
    container.appendChild(canvas);

    const statusP = document.createElement('p');
    statusP.textContent = 'Initializing...';
    statusP.style.marginTop = '10px';
    statusP.style.fontSize = '14px';
    statusP.style.color = '#555';
    container.appendChild(statusP);

    const resultDiv = document.createElement('div');
    resultDiv.style.marginTop = '15px';
    resultDiv.style.padding = '10px';
    resultDiv.style.border = '1px solid #ccc';
    resultDiv.style.borderRadius = '5px';
    resultDiv.style.backgroundColor = '#f9f9f9';
    resultDiv.style.textAlign = 'left';
    resultDiv.style.display = 'none'; // Initially hidden
    container.appendChild(resultDiv);

    try {
        // --- 1. Load OCR Engine ---
        statusP.textContent = 'Loading OCR engine...';
        await loadTesseract();

        // --- 2. Perform OCR ---
        // Prepare language string for Tesseract (e.g., 'eng+fra')
        const tesseractLangs = sourceLang.split(',').map(l => l.trim()).join('+');
        
        const worker = await Tesseract.createWorker(tesseractLangs, 1, {
            logger: m => {
                let statusText = m.status.replace(/_/g, ' ');
                statusText = statusText.charAt(0).toUpperCase() + statusText.slice(1);
                if (m.progress > 0 && m.progress < 1) {
                    const progress = (m.progress * 100).toFixed(0);
                    statusP.textContent = `${statusText}... ${progress}%`;
                } else {
                    statusP.textContent = `${statusText}...`;
                }
            },
        });

        const { data: { text } } = await worker.recognize(canvas);
        await worker.terminate();

        if (!text || text.trim() === '') {
            statusP.textContent = 'No text found in the image.';
            return container;
        }

        // --- 3. Translate Text ---
        statusP.textContent = 'Translating text...';
        
        // Use the first specified language as the source for translation
        const sourceApiLang = getApiLangCode(sourceLang.split(',')[0]);
        const targetApiLang = getApiLangCode(targetLang);

        const apiUrl = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(text)}&langpair=${sourceApiLang}|${targetApiLang}`;

        const response = await fetch(apiUrl);
        if (!response.ok) {
            throw new Error(`Translation API request failed with status ${response.status}`);
        }

        const translationData = await response.json();

        if (translationData.responseStatus !== 200) {
             throw new Error(`Translation API error: ${translationData.responseDetails}`);
        }

        const translatedText = translationData.responseData.translatedText;
        
        // --- 4. Display Results ---
        statusP.style.display = 'none';

        const originalHeader = document.createElement('strong');
        originalHeader.textContent = `Detected Text (${sourceLang.toUpperCase()}):`;
        const originalPre = document.createElement('pre');
        originalPre.textContent = text;
        originalPre.style.whiteSpace = 'pre-wrap';
        originalPre.style.margin = '5px 0 15px 0';
        originalPre.style.padding = '5px';
        originalPre.style.background = '#fff';
        originalPre.style.border = '1px dashed #ddd';

        const translatedHeader = document.createElement('strong');
        translatedHeader.textContent = `Translated Text (${targetLang.toUpperCase()}):`;
        const translatedPre = document.createElement('pre');
        translatedPre.textContent = translatedText;
        translatedPre.style.whiteSpace = 'pre-wrap';
        translatedPre.style.margin = '5px 0';
        translatedPre.style.padding = '5px';
        translatedPre.style.background = '#eef7ff';
        translatedPre.style.border = '1px dashed #bce';
        translatedPre.style.color = '#005a9c';
        translatedPre.style.fontWeight = 'bold';
        
        resultDiv.appendChild(originalHeader);
        resultDiv.appendChild(originalPre);
        resultDiv.appendChild(translatedHeader);
        resultDiv.appendChild(translatedPre);
        resultDiv.style.display = 'block';

    } catch (error) {
        console.error('Image processing failed:', error);
        statusP.textContent = `An error occurred: ${error.message}`;
        statusP.style.color = 'red';
    }

    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

Image Finder Translator is a web-based tool that allows users to extract text from images through Optical Character Recognition (OCR) and translate that text into another language. This tool is particularly useful for individuals who need to convert printed or handwritten text from images and have it translated for various purposes such as studying foreign languages, traveling, and accessing information in different languages. Users simply need to upload an image, specify the source and target languages, and the tool will provide both the original text and its translation.

Leave a Reply

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