Please bookmark this page to avoid losing your image tool!

Image Text Search Tool

(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, searchText = '') {
    // Create main container for the result
    const container = document.createElement('div');
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.width = '100%';
    container.style.boxSizing = 'border-box';
    
    // Create canvas to render image and highlights
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;
    canvas.style.maxWidth = '100%';
    canvas.style.height = 'auto';
    canvas.style.marginBottom = '20px';
    canvas.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);
    container.appendChild(canvas);

    // Create a text container for displaying extracted text lists
    const txtContainer = document.createElement('div');
    txtContainer.style.width = '100%';
    txtContainer.style.padding = '15px';
    txtContainer.style.backgroundColor = '#f8f9fa';
    txtContainer.style.border = '1px solid #dee2e6';
    txtContainer.style.borderRadius = '5px';
    txtContainer.style.fontFamily = 'system-ui, -apple-system, sans-serif';
    txtContainer.style.maxHeight = '300px';
    txtContainer.style.overflowY = 'auto';
    txtContainer.style.boxSizing = 'border-box';
    
    const h3 = document.createElement('h3');
    h3.style.margin = '0 0 10px 0';
    h3.style.fontSize = '1.1rem';
    h3.style.color = '#333';
    h3.textContent = 'Processing image, please wait...';
    txtContainer.appendChild(h3);

    const list = document.createElement('ul');
    list.style.margin = '0';
    list.style.paddingLeft = '20px';
    list.style.color = '#444';
    txtContainer.appendChild(list);
    
    container.appendChild(txtContainer);
    
    const search = searchText.toString().trim().toLowerCase();

    // Dynamically load Tesseract.js for OCR functionality 
    if (!window.Tesseract) {
        await new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js';
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }

    try {
        const { data } = await window.Tesseract.recognize(canvas, 'eng');
        const lines = data.lines || [];
        
        ctx.lineWidth = Math.max(1, Math.min(4, canvas.width * 0.003));
        ctx.strokeStyle = '#ef4444'; // Red outline
        ctx.fillStyle = 'rgba(239, 68, 68, 0.2)'; // semi-transparent red fill
        
        let matchCount = 0;
        const searchWords = search.split(/\s+/);
        
        h3.textContent = 'Rendering matches...';

        for (const line of lines) {
            const lineText = line.text.trim();
            if (lineText.length === 0) continue;
            
            // Check if the current line includes the search string
            if (!search || lineText.toLowerCase().includes(search)) {
                matchCount++;
                
                // Draw bounding boxes on canvas
                // - Empty search: Highlight everything word by word
                // - Single-word search: Highlight precise matching words
                // - Multi-word phrase search: Highlight entire matched line boundary 
                if (!search) {
                    for (const word of line.words) {
                        const { x0, y0, x1, y1 } = word.bbox;
                        ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
                        ctx.fillRect(x0, y0, x1 - x0, y1 - y0);
                    }
                } else if (searchWords.length === 1) {
                    for (const word of line.words) {
                        if (word.text.toLowerCase().includes(search)) {
                            const { x0, y0, x1, y1 } = word.bbox;
                            ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
                            ctx.fillRect(x0, y0, x1 - x0, y1 - y0);
                        }
                    }
                } else {
                    const { x0, y0, x1, y1 } = line.bbox;
                    ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
                    ctx.fillRect(x0, y0, x1 - x0, y1 - y0);
                }

                // Add to list visualization
                const li = document.createElement('li');
                li.style.marginBottom = '8px';
                li.style.lineHeight = '1.4';
                li.style.wordBreak = 'break-word';
                
                if (search) {
                    const escapedSearch = search.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
                    const regex = new RegExp(`(${escapedSearch})`, 'gi');
                    const highlighted = lineText.replace(regex, '<mark style="background-color: #fef08a; padding: 0 2px; border-radius: 2px;">$1</mark>');
                    li.innerHTML = `${highlighted} <span style="color: #888; font-size: 0.85em;">(Confidence: ${Math.round(line.confidence)}%)</span>`;
                } else {
                    li.textContent = `${lineText} `;
                    const confSpan = document.createElement('span');
                    confSpan.style.color = '#888';
                    confSpan.style.fontSize = '0.85em';
                    confSpan.textContent = `(Confidence: ${Math.round(line.confidence)}%)`;
                    li.appendChild(confSpan);
                }
                list.appendChild(li);
            }
        }
        
        if (matchCount === 0) {
            const noMatch = document.createElement('p');
            noMatch.textContent = search ? `No matches found for "${searchText}".` : 'No text recognized.';
            noMatch.style.color = '#666';
            noMatch.style.fontStyle = 'italic';
            noMatch.style.margin = '0';
            list.replaceWith(noMatch);
            h3.textContent = 'Found Text:';
        } else {
            h3.textContent = search ? `Found Matches (${matchCount}):` : `Found Text (${matchCount} lines):`;
        }
        
    } catch (e) {
        console.error("OCR Error:", e);
        const errP = document.createElement('p');
        errP.style.color = '#dc3545';
        errP.style.margin = '0';
        errP.textContent = 'An error occurred during text recognition. Please try an image with clearer text.';
        list.replaceWith(errP);
        h3.textContent = 'Evaluation Failed';
    }

    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

The Image Text Search Tool uses optical character recognition (OCR) to extract text from images and allows users to search for specific words or phrases within that text. The tool visually highlights the matching text directly on the image and provides a list of the recognized text along with confidence scores. This tool is useful for locating specific information within scanned documents, receipts, screenshots, or photos of signs and labels.

Leave a Reply

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