You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, candidateLangs = 'eng+fra+deu+spa+rus+chi_sim+jpn') {
/**
* Dynamically loads a script into the document head.
* @param {string} src The URL of the script to load.
* @returns {Promise<void>} A promise that resolves when the script is loaded.
*/
const loadScript = (src) => {
return new Promise((resolve, reject) => {
if (document.querySelector(`script[src="${src}"]`)) {
// Script is already loaded or is being loaded.
// Wait for the global object to be available.
const checkGlobal = () => {
if (window.Tesseract) {
resolve();
} else {
setTimeout(checkGlobal, 100);
}
};
checkGlobal();
return;
}
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);
});
};
/**
* Maps Tesseract language codes to full language names.
*/
const langMap = {
afr: "Afrikaans", amh: "Amharic", ara: "Arabic", asm: "Assamese", aze: "Azerbaijani",
bel: "Belarusian", ben: "Bengali", bod: "Tibetan", bos: "Bosnian", bul: "Bulgarian",
cat: "Catalan", ceb: "Cebuano", ces: "Czech", chi_sim: "Chinese (Simplified)",
chi_tra: "Chinese (Traditional)", chr: "Cherokee", cym: "Welsh", dan: "Danish",
deu: "German", dzo: "Dzongkha", ell: "Greek", eng: "English", enm: "English (Middle)",
epo: "Esperanto", est: "Estonian", eus: "Basque", fas: "Persian", fin: "Finnish",
fra: "French", frk: "German (Fraktur)", frm: "French (Middle)", gle: "Irish",
glg: "Galician", grc: "Greek (Ancient)", guj: "Gujarati", hat: "Haitian Creole",
heb: "Hebrew", hin: "Hindi", hrv: "Croatian", hun: "Hungarian", iku: "Inuktitut",
ind: "Indonesian", isl: "Icelandic", ita: "Italian", jav: "Javanese", jpn: "Japanese",
kan: "Kannada", kat: "Georgian", kaz: "Kazakh", khm: "Khmer", kir: "Kirghiz",
kor: "Korean", kur: "Kurdish", lao: "Lao", lat: "Latin", lav: "Latvian",
lit: "Lithuanian", mal: "Malayalam", mar: "Marathi", mkd: "Macedonian",
mlt: "Maltese", msa: "Malay", mya: "Burmese", nep: "Nepali", nld: "Dutch",
nor: "Norwegian", ori: "Oriya", pan: "Punjabi", pol: "Polish", por: "Portuguese",
pus: "Pashto", ron: "Romanian", rus: "Russian", san: "Sanskrit", sin: "Sinhala",
slk: "Slovak", slv: "Slovenian", spa: "Spanish", sqi: "Albanian", srp: "Serbian",
swa: "Swahili", swe: "Swedish", syr: "Syriac", tam: "Tamil", tel: "Telugu",
tgk: "Tajik", tgl: "Tagalog", tha: "Thai", tir: "Tigrinya", tur: "Turkish",
uig: "Uighur", ukr: "Ukrainian", urd: "Urdu", uzb: "Uzbek", vie: "Vietnamese",
yid: "Yiddish"
};
// --- 1. Create UI Elements ---
const container = document.createElement('div');
container.style.fontFamily = 'Arial, sans-serif';
container.style.textAlign = 'center';
container.style.maxWidth = '100%';
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
canvas.style.maxWidth = '100%';
canvas.style.height = 'auto';
canvas.style.border = '1px solid #ddd';
canvas.style.borderRadius = '8px';
const resultDiv = document.createElement('div');
resultDiv.style.marginTop = '15px';
resultDiv.style.padding = '10px';
resultDiv.style.border = '1px solid #ccc';
resultDiv.style.borderRadius = '5px';
resultDiv.style.textAlign = 'left';
resultDiv.textContent = 'Initializing language identifier...';
container.appendChild(canvas);
container.appendChild(resultDiv);
// --- 2. Perform Language Detection using Tesseract.js ---
try {
const TESSERACT_CDN = 'https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js';
await loadScript(TESSERACT_CDN);
resultDiv.textContent = 'Creating recognition worker...';
const worker = await Tesseract.createWorker({
logger: m => {
let statusText = m.status;
if (m.status.includes('loading language')) {
statusText = "Loading language model(s)... this may take a moment on first use.";
}
resultDiv.textContent = `${statusText} (${Math.round(m.progress * 100)}%)`;
}
});
await worker.loadLanguage(candidateLangs);
await worker.initialize(candidateLangs);
const { data } = await worker.recognize(originalImg);
await worker.terminate();
// --- 3. Process and Display Results ---
if (data && data.paragraphs && data.paragraphs.length > 0) {
const langFrequency = {};
let totalConfidence = 0;
let langCount = 0;
data.paragraphs.forEach(p => {
if (p.lang && p.confidence > 0) {
langFrequency[p.lang] = (langFrequency[p.lang] || 0) + 1;
totalConfidence += p.confidence;
langCount++;
}
});
const detectedLangs = Object.keys(langFrequency);
if (detectedLangs.length > 0) {
// Find the most frequently detected language
const dominantLang = detectedLangs.reduce((a, b) => langFrequency[a] > langFrequency[b] ? a : b);
const langName = langMap[dominantLang] || dominantLang.toUpperCase();
const avgConfidence = (totalConfidence / langCount).toFixed(2);
resultDiv.innerHTML = `
<div style="text-align: center;">
<strong style="font-size: 1.1em;">Dominant Language Detected</strong><br>
<span style="font-size: 2em; color: #007bff; font-weight: bold;">${langName}</span><br>
(Average Confidence: ${avgConfidence}%)
</div>
<hr style="margin: 15px 0;">
<strong style="display: block; margin-bottom: 5px;">Recognized Text:</strong>
`;
const textPre = document.createElement('pre');
textPre.textContent = data.text;
textPre.style.whiteSpace = 'pre-wrap';
textPre.style.textAlign = 'left';
textPre.style.padding = '10px';
textPre.style.background = '#f8f9fa';
textPre.style.border = '1px solid #e9ecef';
textPre.style.borderRadius = '4px';
textPre.style.maxHeight = '200px';
textPre.style.overflowY = 'auto';
resultDiv.appendChild(textPre);
} else {
resultDiv.textContent = 'Could not determine a language from the recognized text. The text may be too short or ambiguous.';
}
} else {
resultDiv.textContent = 'Could not recognize any text or language in the image.';
}
} catch (error) {
console.error('Language detection failed:', error);
resultDiv.textContent = 'An error occurred during language detection. Please check the console for details.';
resultDiv.style.color = 'red';
}
// --- 4. Return the Final Element ---
return container;
}
Apply Changes