Please bookmark this page to avoid losing your image tool!

Image Translation Tool For Yandex Pictures

(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 = 'es', sourceLang = 'eng') {

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

    // A simple mock dictionary for translation. A real app would use an API.
    const mockDictionary = {
        'es': {
            'hello': 'hola',
            'world': 'mundo',
            'open': 'abrir',
            'close': 'cerrar',
            'exit': 'salida',
            'warning': 'advertencia',
            'danger': 'peligro',
            'text': 'texto'
        },
        'fr': {
            'hello': 'bonjour',
            'world': 'monde',
            'open': 'ouvrir',
            'close': 'fermer',
            'exit': 'sortie',
            'warning': 'avertissement',
            'danger': 'danger',
            'text': 'texte'
        },
        'de': {
            'hello': 'hallo',
            'world': 'welt',
            'open': 'öffnen',
            'close': 'schließen',
            'exit': 'ausfahrt',
            'warning': 'warnung',
            'danger': 'gefahr',
            'text': 'text'
        }
    };

    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);

    // --- 1. Load OCR Library ---
    // Using Tesseract.js, a popular client-side OCR library.
    // The first execution will be slow as it downloads the library and language data.
    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 Arial";
        ctx.fillText("Error: Could not load the OCR library.", 10, 30);
        return canvas;
    }

    // --- 2. Perform OCR ---
    const loadingMessage = document.createElement('div');
    loadingMessage.style.fontFamily = "Arial, sans-serif";
    loadingMessage.innerText = "Initializing OCR and processing image... This may take a moment.";
    
    // Create a temporary container to show progress
    const tempContainer = document.createElement('div');
    tempContainer.style.position = 'relative';
    const progressCanvas = canvas.cloneNode();
    const pCtx = progressCanvas.getContext('2d');
    pCtx.fillStyle = 'rgba(0,0,0,0.5)';
    pCtx.fillRect(0,0,progressCanvas.width, progressCanvas.height);
    pCtx.fillStyle = 'white';
    pCtx.font = `${Math.min(progressCanvas.width/20, 30)}px Arial`;
    pCtx.textAlign = 'center';
    pCtx.textBaseline = 'middle';
    pCtx.fillText("Processing...", progressCanvas.width/2, progressCanvas.height/2);

    tempContainer.appendChild(originalImg.cloneNode());
    tempContainer.appendChild(progressCanvas);
    progressCanvas.style.position = 'absolute';
    progressCanvas.style.left = '0';
    progressCanvas.style.top = '0';


    const worker = await Tesseract.createWorker(sourceLang, 1, {
        logger: m => console.log(m) // Log OCR progress
    });
    const { data: { lines } } = await worker.recognize(canvas);

    // --- 3. Process Each Detected Line of Text ---
    for (const line of lines) {
        const bbox = line.bbox;
        const originalText = line.text.trim().toLowerCase();

        // --- 3a. Mock Translation ---
        const dictionary = mockDictionary[targetLang] || {};
        const words = originalText.split(/\s+/);
        const translatedWords = words.map(word => dictionary[word] || `[${word}]`);
        const translatedText = translatedWords.join(' ');
        
        if (originalText.length === 0) continue;

        // --- 3b. Inpainting (Covering old text) ---
        // We'll calculate the average color around the bounding box to fill it.
        const border = Math.max(2, Math.floor(bbox.height * 0.1));
        let r = 0, g = 0, b = 0, count = 0;
        
        const samplePoints = [
          { x: bbox.x0 - border, y: bbox.y0 - border },
          { x: bbox.x1 + border, y: bbox.y0 - border },
          { x: bbox.x0 - border, y: bbox.y1 + border },
          { x: bbox.x1 + border, y: bbox.y1 + border },
          { x: bbox.x0 + bbox.width / 2, y: bbox.y0 - border },
          { x: bbox.x0 + bbox.width / 2, y: bbox.y1 + border },
          { x: bbox.x0 - border, y: bbox.y0 + bbox.height / 2 },
          { x: bbox.x1 + border, y: bbox.y0 + bbox.height / 2 },
        ];

        samplePoints.forEach(p => {
          if (p.x >= 0 && p.x < canvas.width && p.y >= 0 && p.y < canvas.height) {
            const pixel = ctx.getImageData(p.x, p.y, 1, 1).data;
            r += pixel[0];
            g += pixel[1];
            b += pixel[2];
            count++;
          }
        });

        if (count > 0) {
            ctx.fillStyle = `rgb(${Math.round(r/count)}, ${Math.round(g/count)}, ${Math.round(b/count)})`;
            ctx.fillRect(bbox.x0, bbox.y0, bbox.width, bbox.height);
        }

        // --- 3c. Render New Text ---
        // Determine if background is light or dark for text color
        const bgColorLuminance = (0.299 * (r/count) + 0.587 * (g/count) + 0.114 * (b/count)) / 255;
        ctx.fillStyle = bgColorLuminance > 0.5 ? 'black' : 'white';

        // Attempt to fit the text inside the original bounding box
        let fontSize = bbox.height * 0.8;
        ctx.font = `${fontSize}px Arial`;
        ctx.textAlign = 'left';
        ctx.textBaseline = 'top';
        
        let textWidth = ctx.measureText(translatedText).width;
        while(textWidth > bbox.width && fontSize > 8) {
             fontSize -= 1;
             ctx.font = `${fontSize}px Arial`;
             textWidth = ctx.measureText(translatedText).width;
        }

        const x = bbox.x0;
        const y = bbox.y0 + (bbox.height - fontSize) / 2; // Center vertically
        ctx.fillText(translatedText, x, y);
    }
    
    // --- 4. Cleanup ---
    await worker.terminate();

    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 Image Translation Tool for Yandex Pictures allows users to translate text within images from one language to another. By utilizing Optical Character Recognition (OCR), the tool extracts text from images, translates the text through a predefined dictionary, and then superimposes the translated text back onto the original image. This tool is useful for individuals needing to translate signs, documents, or any text-containing images, making it valuable for travelers, students, or professionals working with multilingual materials.

Leave a Reply

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