You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, fromLang = 'eng', toLang = 'ru') {
/**
* Dynamically loads the Tesseract.js script if it's not already loaded.
* @returns {Promise<void>} A promise that resolves when the script is loaded.
*/
const loadTesseract = () => {
return new Promise((resolve, reject) => {
if (window.Tesseract) {
return resolve();
}
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(new Error('Failed to load Tesseract.js script.'));
document.head.appendChild(script);
});
};
/**
* Maps 3-letter Tesseract language codes to 2-letter ISO 639-1 codes
* for the translation API.
* @param {string} lang The Tesseract language code (e.g., 'eng', 'rus').
* @returns {string} The corresponding ISO 639-1 code (e.g., 'en', 'ru').
*/
const mapLangCodeForApi = (lang) => {
const map = {
'eng': 'en', 'rus': 'ru', 'spa': 'es', 'fra': 'fr',
'deu': 'de', 'ita': 'it', 'por': 'pt', 'chi_sim': 'zh',
'jpn': 'ja', 'kor': 'ko', 'ara': 'ar', 'hin': 'hi'
};
return map[lang] || lang.substring(0, 2); // Fallback to first two letters
};
// 1. Create a canvas and get its context
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
// Draw the original image first
ctx.drawImage(originalImg, 0, 0);
// 2. Display a "Processing..." message on the canvas
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = `bold ${Math.min(48, canvas.width / 15)}px Arial`;
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Identifying & Translating Text...', canvas.width / 2, canvas.height / 2);
try {
// 3. Load Tesseract.js library
await loadTesseract();
// 4. Create a Tesseract worker and perform OCR
const worker = await Tesseract.createWorker(fromLang);
const { data: { lines } } = await worker.recognize(originalImg);
await worker.terminate();
// 5. Redraw the original image to clear the "Processing" message
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(originalImg, 0, 0);
// 6. Create an array of translation tasks
const fromLangApi = mapLangCodeForApi(fromLang);
const toLangApi = mapLangCodeForApi(toLang);
const translationTasks = lines.map(line => {
// Only process lines with reasonable confidence
if (line.confidence > 50 && line.text.trim().length > 0) {
const textToTranslate = line.text.trim();
const url = `https://api.mymemory.translated.net/get?q=${encodeURIComponent(textToTranslate)}&langpair=${fromLangApi}|${toLangApi}`;
return fetch(url)
.then(response => response.json())
.then(data => {
if (data.responseStatus === 200) {
return {
translatedText: data.responseData.translatedText,
bbox: line.bbox
};
}
return null;
})
.catch(error => {
console.error('Translation API error:', error);
return null;
});
}
return Promise.resolve(null);
});
// 7. Wait for all translations to complete
const results = await Promise.all(translationTasks);
// 8. Draw the results on the canvas
results.forEach(result => {
if (result) {
const { translatedText, bbox } = result;
// Draw a background rectangle to cover the original text
ctx.fillStyle = 'rgba(255, 255, 255, 0.95)';
ctx.fillRect(bbox.x0, bbox.y0, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0);
// Set text properties
ctx.fillStyle = 'black';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const boxWidth = bbox.x1 - bbox.x0;
const boxHeight = bbox.y1 - bbox.y0;
// Auto-adjust font size to fit the bounding box
let fontSize = boxHeight * 0.8; // Start with a reasonable font size
ctx.font = `bold ${fontSize}px Arial`;
while (ctx.measureText(translatedText).width > boxWidth * 0.95 && fontSize > 8) {
fontSize -= 1;
ctx.font = `bold ${fontSize}px Arial`;
}
// Draw the translated text centered in the box
ctx.fillText(translatedText, bbox.x0 + boxWidth / 2, bbox.y0 + boxHeight / 2);
}
});
} catch (error) {
console.error('An error occurred during image processing:', error);
// Display an error message on the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(originalImg, 0, 0);
ctx.fillStyle = 'rgba(200, 0, 0, 0.8)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = `bold ${Math.min(40, canvas.width / 20)}px Arial`;
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Error: Could not process the image.', canvas.width / 2, canvas.height / 2);
}
return canvas;
}
Apply Changes