Please bookmark this page to avoid losing your image tool!

Image Scanner Identifier And Mediateka Search Topic Picker

(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, themeColor = "#00FF41", fontSize = "auto") {
    // Create the main canvas that will be returned
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');

    // Scanning animation variables
    let isScanning = true;
    let scanY = 0;
    let scanDir = 1;
    // Calculate a reasonable speed relative to the image size
    const scanSpeed = Math.max(2, canvas.height / 60);

    // Start the visual scanning loop
    const animate = () => {
        if (!isScanning) return;
        
        // Redraw original image to clear previous scan lines
        ctx.drawImage(originalImg, 0, 0);

        // Draw green trailing scan effect
        ctx.fillStyle = themeColor;
        ctx.globalAlpha = 0.15;
        ctx.fillRect(0, 0, canvas.width, scanY);
        ctx.globalAlpha = 1.0;
        
        // Draw main scan line
        ctx.strokeStyle = themeColor;
        ctx.lineWidth = 3;
        ctx.beginPath();
        ctx.moveTo(0, scanY);
        ctx.lineTo(canvas.width, scanY);
        ctx.stroke();

        // Overlay status text
        const textBgWidth = 230;
        ctx.fillStyle = "rgba(0, 0, 0, 0.8)";
        ctx.fillRect(10, 10, textBgWidth, 36);
        ctx.fillStyle = themeColor;
        ctx.font = "14px monospace";
        ctx.fillText("SCANNING M.E.D.I.A...", 20, 33);

        // Advance scanline
        scanY += scanDir * scanSpeed;
        if (scanY > canvas.height || scanY < 0) {
            scanDir *= -1; // Reverse direction upon hitting the edges
        }

        // Loop
        requestAnimationFrame(animate);
    };
    
    // Kick off animation
    animate();

    // Helper to dynamically load external scripts without duplication
    const loadScript = (src) => new Promise((resolve, reject) => {
        if (document.querySelector(`script[src="${src}"]`)) {
            return resolve();
        }
        const script = document.createElement('script');
        script.src = src;
        script.crossOrigin = "anonymous";
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
    });

    // Run Object Identification & Topic Picking in the background
    (async () => {
        try {
            // Dynamically load TensorFlow.js and the MobileNet model architecture
            if (!window.tf) {
                await loadScript("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.21.0/dist/tf.min.js");
            }
            if (!window.mobilenet) {
                await loadScript("https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@2.1.0/dist/mobilenet.min.js");
            }

            // Load the image classification model
            const model = await window.mobilenet.load();
            
            // Generate predictions (passing originalImg allows TF to use underlying pixel data properly)
            const predictions = await model.classify(originalImg);
            
            // Stop scanning effect visual loop
            isScanning = false;
            
            // Clear animation noise
            ctx.drawImage(originalImg, 0, 0);

            // Determine dimensions for typography and layouts based on image
            const fSize = fontSize === "auto" ? Math.max(14, Math.min(28, canvas.width * 0.04)) : Number(fontSize);
            
            // Get highest prediction
            const topResult = predictions && predictions.length > 0 ? predictions[0] : { className: "UNKNOWN ENTITY", probability: 0 };
            
            // Pick a singular mediateka topic (MobileNet groups by commas usually, so strip the primary class)
            const topics = topResult.className.split(',').map(s => s.trim());
            const mediatekaTopic = topics[0].toUpperCase();

            // Draw a techy/Identifier targeting UI
            const cLen = Math.max(20, Math.min(canvas.width, canvas.height) * 0.1);
            ctx.strokeStyle = themeColor;
            ctx.lineWidth = 4;
            const offset = 15;

            // Target corners (Top-Left, Top-Right, Bottom-Left, Bottom-Right)
            ctx.beginPath(); ctx.moveTo(offset, offset + cLen); ctx.lineTo(offset, offset); ctx.lineTo(offset + cLen, offset); ctx.stroke();
            ctx.beginPath(); ctx.moveTo(canvas.width - offset - cLen, offset); ctx.lineTo(canvas.width - offset, offset); ctx.lineTo(canvas.width - offset, offset + cLen); ctx.stroke();
            ctx.beginPath(); ctx.moveTo(offset, canvas.height - offset - cLen); ctx.lineTo(offset, canvas.height - offset); ctx.lineTo(offset + cLen, canvas.height - offset); ctx.stroke();
            ctx.beginPath(); ctx.moveTo(canvas.width - offset - cLen, canvas.height - offset); ctx.lineTo(canvas.width - offset, canvas.height - offset); ctx.lineTo(canvas.width - offset, canvas.height - offset - cLen); ctx.stroke();

            // Draw Data Readout / Result Box at the bottom
            const boxHeight = fSize * 4;
            const boxY = canvas.height - offset - boxHeight;

            ctx.fillStyle = "rgba(10, 15, 10, 0.85)";
            ctx.fillRect(offset, boxY, canvas.width - (offset * 2), boxHeight);
            ctx.lineWidth = 2;
            ctx.strokeRect(offset, boxY, canvas.width - (offset * 2), boxHeight);

            // Print Header
            ctx.fillStyle = "#FFFFFF";
            ctx.font = `bold ${fSize * 0.85}px monospace`;
            ctx.fillText("MEDIATEKA SEARCH TOPIC:", offset + 15, boxY + fSize * 1.3);

            // Print the Chosen Topic Pick
            ctx.fillStyle = themeColor;
            ctx.font = `bold ${fSize * 1.3}px monospace`;
            // Ensure maximum length to prevent clipping off bounds
            ctx.fillText(mediatekaTopic, offset + 15, boxY + fSize * 2.7);

            // Print the Scanner's confidence interval
            ctx.fillStyle = "#AAAAAA";
            ctx.font = `${fSize * 0.75}px monospace`;
            ctx.fillText(`IDENTIFIER CONFIDENCE: ${(topResult.probability * 100).toFixed(2)}%`, offset + 15, boxY + fSize * 3.6);

        } catch (err) {
            // Handle Loading or Processing Errors cleanly visually too
            isScanning = false;
            ctx.drawImage(originalImg, 0, 0);
            ctx.fillStyle = "rgba(255, 0, 0, 0.8)";
            ctx.fillRect(0, 0, canvas.width, 60);
            ctx.fillStyle = "#FFFFFF";
            ctx.font = "16px monospace";
            ctx.fillText("SCAN ERROR: " + err.message, 10, 35);
        }
    })();

    // Synchronously returns the Canvas Element immediately so it can be appended, 
    // while processing asynchronously overlays on it in realtime.
    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

This tool uses artificial intelligence to automatically identify objects within an image and extract a primary search topic. It features a high-tech scanning animation that overlays on your image, providing a visual readout of the identified entity along with a confidence percentage. This tool is ideal for users looking to quickly categorize visual content, generate metadata for digital libraries, or find specific search terms based on uploaded photos.

Leave a Reply

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