Please bookmark this page to avoid losing your image tool!

Image To Movie 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, titleText = "Image to Movie Search") {
    // 1. Create Main Container
    const container = document.createElement("div");
    container.style.fontFamily = "system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
    container.style.maxWidth = "600px";
    container.style.margin = "0 auto";
    container.style.background = "#ffffff";
    container.style.border = "1px solid #e0e0e0";
    container.style.borderRadius = "12px";
    container.style.boxShadow = "0 4px 12px rgba(0,0,0,0.1)";
    container.style.overflow = "hidden";

    // 2. Header
    const header = document.createElement("div");
    header.style.background = "#1a1a2e";
    header.style.color = "#ffffff";
    header.style.padding = "20px";
    header.style.textAlign = "center";
    
    const title = document.createElement("h2");
    title.innerText = "🎬 " + titleText;
    title.style.margin = "0";
    title.style.fontSize = "24px";
    title.style.fontWeight = "600";
    
    const subtitle = document.createElement("p");
    subtitle.innerText = "Identify anime screenshots or extract text from movie posters";
    subtitle.style.margin = "8px 0 0 0";
    subtitle.style.fontSize = "14px";
    subtitle.style.color = "#a0a0b0";
    
    header.appendChild(title);
    header.appendChild(subtitle);
    container.appendChild(header);

    // 3. Image Preview Area
    const previewBlock = document.createElement("div");
    previewBlock.style.padding = "20px";
    previewBlock.style.textAlign = "center";
    previewBlock.style.background = "#f4f5f7";
    
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    
    // Scale large images to a reasonable maximum width to speed up OCR and API loads
    const maxW = 560;
    let scale = 1;
    if (originalImg.width > maxW) {
        scale = maxW / originalImg.width;
    }
    canvas.width = originalImg.width * scale;
    canvas.height = originalImg.height * scale;
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    
    canvas.style.maxWidth = "100%";
    canvas.style.boxShadow = "0 2px 8px rgba(0,0,0,0.2)";
    canvas.style.borderRadius = "8px";
    previewBlock.appendChild(canvas);
    container.appendChild(previewBlock);

    // 4. Action Buttons Layer
    const actionsBlock = document.createElement("div");
    actionsBlock.style.padding = "0 20px 20px 20px";
    actionsBlock.style.display = "flex";
    actionsBlock.style.gap = "10px";
    actionsBlock.style.justifyContent = "center";
    
    const btnAnime = document.createElement("button");
    btnAnime.innerText = "🔍 Search Anime Scene";
    Object.assign(btnAnime.style, {
        flex: "1",
        padding: "12px",
        background: "#e50914",
        color: "white",
        border: "none",
        borderRadius: "6px",
        fontSize: "14px",
        fontWeight: "bold",
        cursor: "pointer",
        transition: "opacity 0.2s"
    });
    
    const btnPoster = document.createElement("button");
    btnPoster.innerText = "📝 Extract Poster Text";
    Object.assign(btnPoster.style, {
        flex: "1",
        padding: "12px",
        background: "#f5c518",
        color: "#000",
        border: "none",
        borderRadius: "6px",
        fontSize: "14px",
        fontWeight: "bold",
        cursor: "pointer",
        transition: "opacity 0.2s"
    });
    
    // Hover effects
    btnAnime.onmouseenter = () => btnAnime.style.opacity = "0.85";
    btnAnime.onmouseleave = () => btnAnime.style.opacity = "1";
    btnPoster.onmouseenter = () => btnPoster.style.opacity = "0.85";
    btnPoster.onmouseleave = () => btnPoster.style.opacity = "1";

    actionsBlock.appendChild(btnAnime);
    actionsBlock.appendChild(btnPoster);
    container.appendChild(actionsBlock);

    // 5. Results Layer
    const resultsBlock = document.createElement("div");
    resultsBlock.style.padding = "20px";
    resultsBlock.style.minHeight = "80px";
    resultsBlock.style.borderTop = "1px solid #e0e0e0";
    resultsBlock.style.background = "#fff";
    resultsBlock.innerHTML = `<p style="text-align:center; color:#888; font-style:italic; margin:0;">Results will appear here...</p>`;
    container.appendChild(resultsBlock);

    // Helper functions
    const getBlob = () => new Promise(res => canvas.toBlob(res, "image/jpeg", 0.9));
    
    function setButtonsDisabled(state) {
        btnAnime.disabled = state;
        btnPoster.disabled = state;
        btnAnime.style.cursor = state ? 'not-allowed' : 'pointer';
        btnPoster.style.cursor = state ? 'not-allowed' : 'pointer';
        btnAnime.style.opacity = state ? "0.6" : "1";
        btnPoster.style.opacity = state ? "0.6" : "1";
    }

    // --- Search Feature 1: Trace.moe Engine (Anime Scene Reverse Image Search) ---
    btnAnime.onclick = async () => {
        setButtonsDisabled(true);
        resultsBlock.innerHTML = `<div style="text-align:center; color:#666;">
            <p>⌛ Uploading and searching anime database (trace.moe)...</p>
        </div>`;
        
        try {
            const blob = await getBlob();
            const formData = new FormData();
            formData.append("image", blob);

            const response = await fetch("https://api.trace.moe/search", {
                method: "POST",
                body: formData
            });
            
            if (!response.ok) throw new Error("API responded with an error");
            
            const data = await response.json();
            
            if (data.result && data.result.length > 0) {
                const bestMatch = data.result[0];
                const accuracy = (bestMatch.similarity * 100).toFixed(1);
                const isAccurate = bestMatch.similarity > 0.85;
                
                // Clean filename to look more like a standard title
                const titleMatch = bestMatch.filename.replace(/\.[^/.]+$/, "").replace(/\[.*?\]/g, '').replace(/_|-/g, ' ').trim();
                
                resultsBlock.innerHTML = `
                    <h4 style="margin:0 0 12px 0; color:#1a1a2e; font-size: 16px;">Anime Match Found!</h4>
                    <div style="background:#f4f5f7; padding:15px; border-radius:8px; display:flex; flex-direction:column; gap:8px; font-size:14px;">
                        <div><strong style="color:#333;">Title:</strong> ${titleMatch}</div>
                        <div><strong style="color:#333;">Episode:</strong> ${bestMatch.episode || "Movie/OVA (N/A)"}</div>
                        <div>
                            <strong style="color:#333;">Confidence:</strong> 
                            <span style="color:${isAccurate ? '#28a745' : '#e50914'}; font-weight:bold;">${accuracy}%</span>
                        </div>
                        ${bestMatch.video ? `<video src="${bestMatch.video}" controls autoplay loop style="width:100%; border-radius:6px; margin-top:10px; max-height:220px; object-fit:contain; background:#000;"></video>` : ''}
                    </div>
                `;
            } else {
                resultsBlock.innerHTML = `<p style="color:#e50914; text-align:center; font-weight:bold;">No anime match found in the database.</p>`;
            }
        } catch (err) {
            resultsBlock.innerHTML = `<p style="color:red; text-align:center;">Error: ${err.message}</p>`;
        } finally {
            setButtonsDisabled(false);
        }
    };

    // --- Search Feature 2: Tesseract OCR (Movie Poster / Scene Text Extraction) ---
    btnPoster.onclick = async () => {
        setButtonsDisabled(true);
        resultsBlock.innerHTML = `<div style="text-align:center; color:#666;">
            <p>⌛ Loading OCR engine...</p>
        </div>`;
            
        try {
            // Dinamically load Tesseract.js if not available
            if (!window.Tesseract) {
                await new Promise((resolve, reject) => {
                    const script = document.createElement("script");
                    script.src = "https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js";
                    script.onload = resolve;
                    script.onerror = reject;
                    document.head.appendChild(script);
                });
            }
            
            resultsBlock.innerHTML = `<div style="text-align:center; color:#666;">
                <p>⌛ Scanning image for text... Please wait.</p>
            </div>`;
            
            const result = await window.Tesseract.recognize(canvas, "eng", {
                logger: m => {
                    if (m.status === 'recognizing text') {
                        const progressIndicator = Math.round(m.progress * 100);
                        resultsBlock.innerHTML = `<div style="text-align:center; color:#666;">
                            <p>⌛ Recognizing text... ${progressIndicator}%</p>
                        </div>`;
                    }
                }
            });
            
            const rawText = result.data.text.trim();
            
            if (rawText) {
                // Formatting readable query based on dominant text
                const cleanText = rawText.replace(/\n+/g, " ").trim();
                const keywords = cleanText.split(" ").slice(0, 15).join(" ");
                const encodedQuery = encodeURIComponent(keywords.replace(/[^a-zA-Z0-9 ]/g, '')); // Sanitize output format
                
                resultsBlock.innerHTML = `
                    <h4 style="margin:0 0 12px 0; color:#1a1a2e; font-size:16px;">Extracted Poster Text:</h4>
                    <div style="background:#f4f5f7; padding:15px; border-radius:8px; margin-bottom:15px; color:#333;">
                        <em style="font-size:13px; line-height: 1.4;">"${rawText.replace(/\n/g, '<br>')}"</em>
                    </div>
                    <h4 style="margin:0 0 10px 0; font-size:14px; color:#1a1a2e; text-align:center;">Search for this movie on:</h4>
                    <div style="display:flex; gap:10px; font-size:13px;">
                        <a href="https://www.imdb.com/find?q=${encodedQuery}" target="_blank" style="flex:1; text-align:center; padding:10px; background:#f5c518; color:#000; text-decoration:none; border-radius:6px; font-weight:bold; transition: background 0.2s;" onmouseenter="this.style.background='#d8ad15'" onmouseleave="this.style.background='#f5c518'">IMDB</a>
                        <a href="https://www.themoviedb.org/search?query=${encodedQuery}" target="_blank" style="flex:1; text-align:center; padding:10px; background:#0d253f; color:#fff; text-decoration:none; border-radius:6px; font-weight:bold; transition: background 0.2s;" onmouseenter="this.style.background='#081829'" onmouseleave="this.style.background='#0d253f'">TMDB</a>
                        <a href="https://www.google.com/search?q=${encodedQuery}+movie" target="_blank" style="flex:1; text-align:center; padding:10px; background:#4285F4; color:#fff; text-decoration:none; border-radius:6px; font-weight:bold; transition: background 0.2s;" onmouseenter="this.style.background='#3367d6'" onmouseleave="this.style.background='#4285F4'">Google</a>
                    </div>
                `;
            } else {
                resultsBlock.innerHTML = `<p style="color:#e50914; text-align:center; font-weight:bold;">Could not detect any readable text from the image.</p>`;
            }
            
        } catch (err) {
            resultsBlock.innerHTML = `<p style="color:red; text-align:center;">Error: ${err.message}</p>`;
        } finally {
            setButtonsDisabled(false);
        }
    };

    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 To Movie Search Tool is a dual-purpose utility designed to help users identify media content from images. It features an anime scene recognition engine that uses reverse image search to identify specific anime titles, episodes, and even provides video clips of the matched scene. Additionally, it includes an OCR (Optical Character Recognition) feature that extracts text from movie posters or film stills, allowing users to quickly search for those titles on platforms like IMDb, TMDB, or Google. This tool is ideal for anime fans looking to find the source of a screenshot or movie enthusiasts trying to identify a film from a poster.

Leave a Reply

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