You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, maxIdentifications = "5") {
// 1. Create main wrapper container
const container = document.createElement('div');
container.style.fontFamily = 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
container.style.width = '100%';
container.style.maxWidth = '600px';
container.style.margin = '0 auto';
container.style.padding = '24px';
container.style.boxSizing = 'border-box';
container.style.border = '1px solid #eaeaea';
container.style.borderRadius = '16px';
container.style.backgroundColor = '#ffffff';
container.style.boxShadow = '0 10px 25px rgba(0,0,0,0.08)';
container.style.color = '#333';
// 2. Title
const title = document.createElement('h2');
title.textContent = 'Logopedia AI Identifier';
title.style.margin = '0 0 20px 0';
title.style.textAlign = 'center';
title.style.fontSize = '22px';
title.style.fontWeight = '700';
container.appendChild(title);
// 3. Image display box
const imgContainer = document.createElement('div');
imgContainer.style.textAlign = 'center';
imgContainer.style.marginBottom = '20px';
imgContainer.style.backgroundColor = '#f8f9fa';
imgContainer.style.padding = '20px';
imgContainer.style.borderRadius = '12px';
imgContainer.style.border = '1px dashed #ced4da';
const img = document.createElement('img');
img.src = originalImg.src;
img.style.maxWidth = '100%';
img.style.maxHeight = '220px';
img.style.objectFit = 'contain';
imgContainer.appendChild(img);
container.appendChild(imgContainer);
// 4. Loading Status Indicator
const statusLabel = document.createElement('div');
statusLabel.innerHTML = '<strong>⚙️ Analyzing logo...</strong><br/><span style="font-size: 13px; color: #6c757d;">Loading AI models and scanning for objects & text.</span>';
statusLabel.style.textAlign = 'center';
statusLabel.style.padding = '15px';
statusLabel.style.backgroundColor = '#e9ecef';
statusLabel.style.borderRadius = '8px';
statusLabel.style.color = '#495057';
statusLabel.style.lineHeight = '1.5';
container.appendChild(statusLabel);
// 5. Results Section
const resultsContainer = document.createElement('div');
resultsContainer.style.display = 'flex';
resultsContainer.style.flexDirection = 'column';
resultsContainer.style.gap = '16px';
container.appendChild(resultsContainer);
// Prepare an internal scaled-down transparent-safe canvas for identification tools
// to bypass CORS and improve performance.
const tempCanvas = document.createElement('canvas');
const MAX_DIM = 600;
let imgW = originalImg.naturalWidth || originalImg.width || MAX_DIM;
let imgH = originalImg.naturalHeight || originalImg.height || MAX_DIM;
if (imgW > MAX_DIM || imgH > MAX_DIM) {
const ratio = Math.min(MAX_DIM / imgW, MAX_DIM / imgH);
imgW = Math.round(imgW * ratio);
imgH = Math.round(imgH * ratio);
}
tempCanvas.width = imgW;
tempCanvas.height = imgH;
const ctx = tempCanvas.getContext('2d');
// Fill white background just in case the original image is a transparent PNG logo
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
ctx.drawImage(originalImg, 0, 0, tempCanvas.width, tempCanvas.height);
// Utility function: dynamically load a script and wait until the global object is available
const loadScript = (id, src, globalVar) => {
return new Promise((resolve, reject) => {
if (window[globalVar]) return resolve(window[globalVar]);
if (document.getElementById(id)) {
const check = setInterval(() => {
if (window[globalVar]) {
clearInterval(check);
resolve(window[globalVar]);
}
}, 100);
setTimeout(() => { clearInterval(check); reject(new Error('Timeout')); }, 8000);
return;
}
const script = document.createElement('script');
script.id = id;
script.src = src;
script.onload = () => resolve(window[globalVar]);
script.onerror = reject;
document.head.appendChild(script);
});
};
// Execute background analysis
(async () => {
const numPredictions = parseInt(maxIdentifications, 10) || 5;
// Load ml5.js (Image Classification) and Tesseract.js (OCR for Logo Text)
const pMl5 = loadScript('ml5-ai-lib', 'https://unpkg.com/ml5@0.12.2/dist/ml5.min.js', 'ml5');
const pTesseract = loadScript('tesseract-ai-lib', 'https://unpkg.com/tesseract.js@5/dist/tesseract.min.js', 'Tesseract');
const [ml5Lib, tesseractLib] = await Promise.allSettled([pMl5, pTesseract]);
const tasks = [];
// 1. Text Extraction Task
if (tesseractLib.status === 'fulfilled' && tesseractLib.value) {
tasks.push((async () => {
try {
const Tesseract = tesseractLib.value;
const result = await Tesseract.recognize(tempCanvas, 'eng', { logger: () => {} });
return { type: 'ocr', text: result.data.text.trim() };
} catch (e) {
console.error('OCR Error:', e);
return { type: 'ocr', text: '' };
}
})());
}
// 2. Object/Subject Classification Task
if (ml5Lib.status === 'fulfilled' && ml5Lib.value) {
tasks.push((async () => {
try {
const ml5 = ml5Lib.value;
const classifier = await ml5.imageClassifier('MobileNet');
const results = await classifier.classify(tempCanvas, numPredictions);
return { type: 'ml5', results };
} catch (e) {
console.error('Classification Error:', e);
return { type: 'ml5', results: [] };
}
})());
}
if (tasks.length === 0) {
statusLabel.innerHTML = '❌ Failed to load AI modules. Check your internet connection.';
statusLabel.style.backgroundColor = '#f8d7da';
statusLabel.style.color = '#721c24';
return;
}
const runAnalysis = await Promise.allSettled(tasks);
// Processing Complete
statusLabel.style.display = 'none';
let ocrText = '';
let imageTags = [];
runAnalysis.forEach(task => {
if (task.status === 'fulfilled') {
if (task.value.type === 'ocr') ocrText = task.value.text;
if (task.value.type === 'ml5') imageTags = task.value.results;
}
});
// UI rendering: Logo Brand Text section
if (ocrText.length > 0) {
const ocrCard = document.createElement('div');
ocrCard.style.padding = '16px';
ocrCard.style.border = '1px solid #b6d4fe';
ocrCard.style.backgroundColor = '#cce5ff';
ocrCard.style.borderRadius = '10px';
const txtTitle = document.createElement('div');
txtTitle.innerHTML = '📝 <strong>Extracted Logo Text:</strong>';
txtTitle.style.marginBottom = '10px';
txtTitle.style.color = '#004085';
txtTitle.style.fontSize = '15px';
const textVal = document.createElement('div');
textVal.style.fontSize = '18px';
textVal.style.fontWeight = 'bold';
textVal.style.fontFamily = 'monospace';
textVal.style.color = '#002752';
textVal.style.whiteSpace = 'pre-wrap';
textVal.style.wordBreak = 'break-word';
textVal.textContent = ocrText;
ocrCard.appendChild(txtTitle);
ocrCard.appendChild(textVal);
resultsContainer.appendChild(ocrCard);
} else {
const ocrCard = document.createElement('div');
ocrCard.style.padding = '12px 16px';
ocrCard.style.border = '1px solid #e2e3e5';
ocrCard.style.backgroundColor = '#f8f9fa';
ocrCard.style.borderRadius = '10px';
ocrCard.style.color = '#6c757d';
ocrCard.style.fontStyle = 'italic';
ocrCard.style.fontSize = '14px';
ocrCard.innerHTML = '📝 No prominent clear text identified in this logo.';
resultsContainer.appendChild(ocrCard);
}
// UI rendering: AI Subject Classification section
if (imageTags.length > 0) {
const mlCard = document.createElement('div');
mlCard.style.padding = '16px';
mlCard.style.border = '1px solid #d1e7dd';
mlCard.style.backgroundColor = '#d1e7dd';
mlCard.style.borderRadius = '10px';
const listTitle = document.createElement('div');
listTitle.innerHTML = '🔍 <strong>Identified Brand Objects/Concepts:</strong>';
listTitle.style.marginBottom = '14px';
listTitle.style.color = '#0f5132';
listTitle.style.fontSize = '15px';
mlCard.appendChild(listTitle);
const tagsList = document.createElement('div');
tagsList.style.display = 'flex';
tagsList.style.flexDirection = 'column';
tagsList.style.gap = '8px';
imageTags.forEach(tag => {
const row = document.createElement('div');
row.style.display = 'flex';
row.style.justifyContent = 'space-between';
row.style.alignItems = 'center';
row.style.backgroundColor = 'rgba(255, 255, 255, 0.65)';
row.style.padding = '10px 14px';
row.style.borderRadius = '8px';
row.style.boxShadow = '0 1px 3px rgba(0,0,0,0.05)';
const name = document.createElement('span');
name.textContent = tag.label.split(',')[0].toUpperCase();
name.style.fontWeight = 'bold';
name.style.color = '#146c43';
name.style.fontSize = '14px';
const score = document.createElement('span');
score.textContent = Math.round(tag.confidence * 100) + '% Match';
score.style.backgroundColor = '#198754';
score.style.color = '#ffffff';
score.style.padding = '3px 8px';
score.style.borderRadius = '12px';
score.style.fontSize = '12px';
score.style.fontWeight = 'bold';
row.appendChild(name);
row.appendChild(score);
tagsList.appendChild(row);
});
mlCard.appendChild(tagsList);
resultsContainer.appendChild(mlCard);
}
})();
// Returns immediately while AI processes in the background
return container;
}
Apply Changes