You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, language = 'eng') {
// Create the main container div
const container = document.createElement('div');
container.style.position = 'relative';
container.style.display = 'inline-block';
container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
container.style.maxWidth = '100%';
container.style.overflow = 'hidden';
container.style.borderRadius = '8px';
container.style.boxShadow = '0 4px 6px rgba(0,0,0,0.3)';
// Create and append the canvas to show the original image
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
canvas.style.maxWidth = '100%';
canvas.style.display = 'block';
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
container.appendChild(canvas);
// Create the scanner overlay UI
const overlay = document.createElement('div');
overlay.style.position = 'absolute';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
overlay.style.display = 'flex';
overlay.style.flexDirection = 'column';
overlay.style.justifyContent = 'center';
overlay.style.alignItems = 'center';
overlay.style.color = '#fff';
overlay.style.transition = 'background-color 0.5s ease';
// Status text container
const statusContainer = document.createElement('div');
statusContainer.innerHTML = 'Analyzing Image...';
statusContainer.style.fontSize = '24px';
statusContainer.style.fontWeight = 'bold';
statusContainer.style.textAlign = 'center';
statusContainer.style.letterSpacing = '1px';
statusContainer.style.textShadow = '0 2px 4px rgba(0,0,0,0.8)';
// Animated scanning line
const scanline = document.createElement('div');
scanline.style.position = 'absolute';
scanline.style.top = '0';
scanline.style.left = '0';
scanline.style.width = '100%';
scanline.style.height = '3px';
scanline.style.backgroundColor = '#00ffcc';
scanline.style.boxShadow = '0 0 15px 2px #00ffcc, 0 0 5px 1px #00ffcc inset';
scanline.style.transition = 'top 0.1s linear';
overlay.appendChild(statusContainer);
overlay.appendChild(scanline);
container.appendChild(overlay);
// Scanline animation loop
let scanDirection = 1;
let scanPos = 0;
const scanInterval = setInterval(() => {
scanPos += scanDirection * 2;
if (scanPos >= 98 || scanPos <= 0) {
scanDirection *= -1;
}
scanline.style.top = scanPos + '%';
}, 30);
// Run OCR asynchronously
(async () => {
try {
// Dynamically load Tesseract.js if not available
if (!window.Tesseract) {
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://unpkg.com/tesseract.js@4.1.1/dist/tesseract.min.js';
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// Draw image on a temporary canvas, scaled down for faster OCR processing
const MAX_OCR_DIM = 1200;
let scale = 1;
if (originalImg.width > MAX_OCR_DIM || originalImg.height > MAX_OCR_DIM) {
scale = Math.min(MAX_OCR_DIM / originalImg.width, MAX_OCR_DIM / originalImg.height);
}
const ocrCanvas = document.createElement('canvas');
ocrCanvas.width = originalImg.width * scale;
ocrCanvas.height = originalImg.height * scale;
const ocrCtx = ocrCanvas.getContext('2d');
// Enhance contrast slightly for better OCR
ocrCtx.filter = 'contrast(120%) grayscale(100%)';
ocrCtx.drawImage(originalImg, 0, 0, ocrCanvas.width, ocrCanvas.height);
// Extract text
const result = await window.Tesseract.recognize(ocrCanvas, language);
const text = result.data.text;
// Information Extraction Heuristics
let year = "Unknown";
let studio = "Unknown";
// 1. Identify Year (Look for 18xx, 19xx, 20xx)
const yearMatch = text.match(/\b(18\d{2}|19\d{2}|20\d{2})\b/);
if (yearMatch) {
year = yearMatch[1];
}
// 2. Identify Studio/Company (Look for common keywords)
const studioRegex = /([A-Z][A-Za-z0-9&'\- ]{0,35}(?:Studio|Pictures|Entertainment|Films|Productions|Bros|Company|Inc|Corp|Animation|Media|Network|Cinema)s?)\b/i;
const studioMatch = text.match(studioRegex);
if (studioMatch) {
studio = studioMatch[1].replace(/\n/g, ' ').trim();
} else if (text.trim().length > 0) {
// Fallback: If no keyword matched but text exists, pick the most prominent first word/line
const lines = text.split('\n').filter(l => /[A-Za-z]{3,}/.test(l));
if (lines.length > 0) {
studio = lines[0].substring(0, 40).trim();
}
}
// Stop animations and format final result display
clearInterval(scanInterval);
scanline.style.display = 'none';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.85)';
overlay.style.backdropFilter = 'blur(4px)';
statusContainer.innerHTML = `
<div style="color: #00ffcc; font-size: 32px; margin-bottom: 20px;">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 8px;"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
Scan Complete
</div>
<div style="background: rgba(255,255,255,0.08); padding: 25px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.2); width: 90%; max-width: 450px; text-align: left; margin: 0 auto; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
<div style="margin-bottom: 20px;">
<div style="color: #00ffcc; font-size: 13px; text-transform: uppercase; letter-spacing: 1.5px; margin-bottom: 5px;">Identified Studio/Company</div>
<div style="color: #fff; font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.8); line-height: 1.2;">
${studio}
</div>
</div>
<div>
<div style="color: #00ffcc; font-size: 13px; text-transform: uppercase; letter-spacing: 1.5px; margin-bottom: 5px;">Identified Year</div>
<div style="color: #fff; font-size: 24px; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.8);">
${year}
</div>
</div>
</div>
`;
} catch(e) {
clearInterval(scanInterval);
scanline.style.display = 'none';
statusContainer.innerHTML = `
<div style="color: #ff4444; font-size: 24px;">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 8px;"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
Scanner Error
</div>
<div style="font-size: 16px; margin-top: 10px; color: #ccc;">${e.message}</div>
`;
}
})();
// Return the container synchronously while async OCR runs in the background
return container;
}
Apply Changes