Please bookmark this page to avoid losing your image tool!

Image Name Translator Scene Identifier

(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.
/**
 * Identifies the main subject or scene in an image using a pre-trained model,
 * and translates its name into a specified language. The result is presented
 * as the original image with the translated name overlaid.
 *
 * This function dynamically loads TensorFlow.js and the MobileNet model to perform
 * image classification directly in the browser.
 *
 * @param {Image} originalImg The original javascript Image object to process.
 * @param {string} targetLanguage The target language for translation (e.g., 'es', 'fr', 'de'). Defaults to 'es' (Spanish).
 * @param {number} confidenceThreshold The minimum confidence score (0.0 to 1.0) required for a prediction to be considered valid. Defaults to 0.3.
 * @returns {Promise<HTMLCanvasElement>} A Promise that resolves with a canvas element containing the original image with the identified and translated name overlaid.
 */
async function processImage(originalImg, targetLanguage = 'es', confidenceThreshold = 0.3) {

    // Helper function to dynamically load a script and return a promise
    const loadScript = (src) => {
        return new Promise((resolve, reject) => {
            // Resolve immediately if script already exists
            if (document.querySelector(`script[src="${src}"]`)) {
                return resolve();
            }
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Script load error for ${src}`));
            document.head.appendChild(script);
        });
    };

    // Create the output canvas and draw the original image
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);

    // Display a loading message on the canvas while the model loads
    const drawOverlayMessage = (message) => {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'white';
        ctx.font = `bold ${Math.max(18, canvas.width / 20)}px Arial`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(message, canvas.width / 2, canvas.height / 2);
    };
    
    drawOverlayMessage('Loading AI Model...');

    // Load TensorFlow.js and the MobileNet model
    try {
        await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.11.0/dist/tf.min.js');
        await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@2.1.0/dist/mobilenet.min.js');
    } catch (error) {
        console.error(error);
        ctx.drawImage(originalImg, 0, 0); // Clear overlay
        drawOverlayMessage('Error: Failed to load AI model.');
        return canvas;
    }

    drawOverlayMessage('Analyzing Scene...');

    let predictions;
    try {
        // Load the MobileNet model.
        const model = await mobilenet.load();
        // Classify the image.
        predictions = await model.classify(originalImg);
    } catch(e) {
        console.error(e);
        ctx.drawImage(originalImg, 0, 0); // Clear overlay
        drawOverlayMessage('Error: Could not analyze image.');
        return canvas;
    }

    // Filter predictions by confidence and get the top result
    const validPredictions = predictions.filter(p => p.probability >= confidenceThreshold);
    const topPrediction = validPredictions.length > 0 ? validPredictions[0] : null;

    let originalName = 'Scene not identified';
    if (topPrediction) {
        // The result can be "Siamese cat, Siamese", so we take the first part.
        originalName = topPrediction.className.split(',')[0];
    }

    // --- Translation Logic ---
    const translations = {
        'rocking chair': { es: 'mecedora', fr: 'fauteuil à bascule', de: 'Schaukelstuhl' },
        'golden retriever': { es: 'golden retriever', fr: 'golden retriever', de: 'Golden Retriever' },
        'sports car': { es: 'coche deportivo', fr: 'voiture de sport', de: 'Sportwagen' },
        'street sign': { es: 'señal de tráfico', fr: 'panneau de signalisation', de: 'Verkehrszeichen' },
        'desktop computer': { es: 'computadora de escritorio', fr: 'ordinateur de bureau', de: 'Desktop-Computer' },
        'beach': { es: 'playa', fr: 'plage', de: 'Strand' },
        'volcano': { es: 'volcán', fr: 'volcan', de: 'Vulkan' },
        'lakeside': { es: 'orilla del lago', fr: 'bord du lac', de: 'Seeufer' },
        'cat': { es: 'gato', fr: 'chat', de: 'Katze' },
        'dog': { es: 'perro', fr: 'chien', de: 'Hund' },
        'car': { es: 'coche', fr: 'voiture', de: 'Auto' },
        'computer': { es: 'computadora', fr: 'ordinateur', de: 'Computer' },
        'keyboard': { es: 'teclado', fr: 'clavier', de: 'Tastatur' },
        'mountain': { es: 'montaña', fr: 'montagne', de: 'Berg' },
        'ocean': { es: 'océano', fr: 'océan', de: 'Ozean' },
        'house': { es: 'casa', fr: 'maison', de: 'Haus' },
        'tree': { es: 'árbol', fr: 'arbre', de: 'Baum' },
        'flower': { es: 'flor', fr: 'fleur', de: 'Blume' },
        'sky': { es: 'cielo', fr: 'ciel', de: 'Himmel' },
        'seashore': { es: 'costa', fr: 'rivage', de: 'Küste' },
    };

    let translatedName = originalName;
    let translatableKey = null;

    // Find the best matching key from our dictionary in the MobileNet result
    const knownKeys = Object.keys(translations).sort((a,b) => b.length - a.length); // Prioritize longer keys
    for (const key of knownKeys) {
        if (originalName.toLowerCase().includes(key)) {
            translatableKey = key;
            break;
        }
    }

    if (translatableKey && translations[translatableKey][targetLanguage]) {
        translatedName = translations[translatableKey][targetLanguage];
    }
    
    // --- Render Final Output ---
    ctx.drawImage(originalImg, 0, 0); // Redraw original image to clear the overlay

    const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);

    const textToDisplay = (translatedName.toLowerCase() !== originalName.toLowerCase())
        ? `${capitalize(translatedName)} (${capitalize(originalName)})`
        : capitalize(originalName);

    // Calculate font size based on image width for responsiveness
    const fontSize = Math.max(16, Math.floor(canvas.width / 30));
    ctx.font = `bold ${fontSize}px 'Helvetica Neue', Arial, sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';

    // Add a semi-transparent background for the text for better readability
    const padding = fontSize * 0.5;
    const textMetrics = ctx.measureText(textToDisplay);
    const textHeight = fontSize;
    const boxHeight = textHeight + padding;
    
    ctx.fillStyle = 'rgba(0, 0, 0, 0.65)';
    ctx.fillRect(0, canvas.height - boxHeight, canvas.width, boxHeight);

    // Draw the final text
    ctx.fillStyle = 'white';
    ctx.fillText(textToDisplay, canvas.width / 2, canvas.height - (padding / 2));

    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 Name Translator Scene Identifier tool is designed to analyze and identify the main subject or scene depicted in an image. It utilizes a pre-trained machine learning model to classify the image and then provides a translation of the identified subject’s name into a specified language. The result is displayed as the original image with the translated name overlaid, enhancing your images with informative labels. This tool can be particularly useful for educators, content creators, and travelers looking to add multilingual descriptions to their images, making it easier to share and understand visual content across different languages.

Leave a Reply

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