You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, fallbackText = "The quick brown fox jumps over the lazy dog") {
// Create the main container div
const container = document.createElement('div');
container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
container.style.padding = '20px';
container.style.maxWidth = '900px';
container.style.margin = '0 auto';
container.style.color = '#333';
container.style.backgroundColor = '#f9f9f9';
container.style.borderRadius = '8px';
container.style.boxShadow = '0 4px 12px rgba(0,0,0,0.1)';
// App header
const header = document.createElement('h2');
header.innerText = 'Image Font Search & Preview';
header.style.marginTop = '0';
container.appendChild(header);
// Display the original image
const imgWrapper = document.createElement('div');
imgWrapper.style.textAlign = 'center';
imgWrapper.style.marginBottom = '20px';
const imgDisplay = document.createElement('img');
imgDisplay.src = originalImg.src;
imgDisplay.style.maxWidth = '100%';
imgDisplay.style.maxHeight = '250px';
imgDisplay.style.border = '1px solid #ddd';
imgDisplay.style.borderRadius = '4px';
imgWrapper.appendChild(imgDisplay);
container.appendChild(imgWrapper);
// Status / Loading Indicator
const statusPanel = document.createElement('div');
statusPanel.style.backgroundColor = '#eef2ff';
statusPanel.style.border = '1px solid #c7d2fe';
statusPanel.style.padding = '15px';
statusPanel.style.borderRadius = '6px';
statusPanel.style.marginBottom = '20px';
statusPanel.style.fontWeight = '500';
statusPanel.style.color = '#4338ca';
container.appendChild(statusPanel);
// Display results grid
const resultsContainer = document.createElement('div');
container.appendChild(resultsContainer);
// Prepare Google Fonts for "Topic" Search
const fontsToSearch = [
'Roboto', 'Open Sans', 'Lato', 'Montserrat', 'Oswald',
'Merriweather', 'Playfair Display', 'Lora', 'PT Serif',
'Pacifico', 'Caveat', 'Great Vibes', 'Lobster',
'Righteous', 'Cinzel', 'Bebas Neue', 'Creepster',
'Press Start 2P', 'Bangers', 'Special Elite'
];
// Load Google fonts dynamically
const fontLink = document.createElement('link');
fontLink.rel = 'stylesheet';
const families = fontsToSearch.map(f => `family=${f.replace(/ /g, '+')}`).join('&');
fontLink.href = `https://fonts.googleapis.com/css2?${families}&display=swap`;
document.head.appendChild(fontLink);
// Draw the image to a temporary canvas to ensure standard data reading for Tesseract
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
try {
// Load Tesseract.js if not available
if (!window.Tesseract) {
statusPanel.innerText = "Loading Tesseract.js (Optical Character Recognition) engine...";
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js';
document.head.appendChild(script);
await new Promise((resolve, reject) => {
script.onload = resolve;
script.onerror = () => reject(new Error("Failed to load Tesseract.js"));
});
}
statusPanel.innerText = "Initializing image analysis and text extraction...";
// Perform OCR to extract text from the image
const result = await window.Tesseract.recognize(
canvas,
'eng',
{ logger: m => {
if(m.status === 'recognizing text' && m.progress) {
statusPanel.innerText = `Recognizing text in image: ${Math.floor(m.progress * 100)}%`;
}
}}
);
// Sanitize and check extracted text
let extractedText = result.data.text.trim().replace(/\n/g, ' ');
let isFallback = false;
// If no text is found, inform the user and use fallback text to preview fonts
if (!extractedText || extractedText.length < 2) {
extractedText = fallbackText;
isFallback = true;
statusPanel.innerHTML = `<strong>No text found in image.</strong><br/>Using fallback text to preview search fonts.`;
} else {
// Limit text string to decent preview length
if (extractedText.length > 60) {
extractedText = extractedText.substring(0, 60) + '...';
}
statusPanel.innerHTML = `<strong>Extracted Text:</strong> "${extractedText}"<br/>Searching and rendering similar potential fonts below:`;
}
statusPanel.style.color = '#065f46';
statusPanel.style.backgroundColor = '#d1fae5';
statusPanel.style.borderColor = '#10b981';
// Render standard font options for the user to compare visibly
resultsContainer.style.display = 'grid';
resultsContainer.style.gridTemplateColumns = 'repeat(auto-fill, minmax(280px, 1fr))';
resultsContainer.style.gap = '20px';
resultsContainer.style.marginTop = '20px';
fontsToSearch.forEach(font => {
const card = document.createElement('div');
card.style.border = '1px solid #e5e7eb';
card.style.padding = '15px';
card.style.borderRadius = '8px';
card.style.background = '#ffffff';
card.style.boxShadow = '0 2px 4px rgba(0,0,0,0.05)';
card.style.transition = 'transform 0.2s, box-shadow 0.2s';
card.onmouseover = () => {
card.style.transform = 'translateY(-2px)';
card.style.boxShadow = '0 6px 12px rgba(0,0,0,0.1)';
};
card.onmouseout = () => {
card.style.transform = 'translateY(0)';
card.style.boxShadow = '0 2px 4px rgba(0,0,0,0.05)';
};
const title = document.createElement('h3');
title.innerText = font;
title.style.margin = '0 0 12px 0';
title.style.fontSize = '12px';
title.style.textTransform = 'uppercase';
title.style.letterSpacing = '1px';
title.style.color = '#9ca3af';
const preview = document.createElement('div');
preview.innerText = extractedText;
preview.style.fontFamily = `"${font}", sans-serif`;
preview.style.fontSize = '26px';
preview.style.lineHeight = '1.3';
preview.style.wordBreak = 'break-word';
preview.style.color = '#111827';
card.appendChild(title);
card.appendChild(preview);
resultsContainer.appendChild(card);
});
} catch (err) {
statusPanel.style.color = '#991b1b';
statusPanel.style.backgroundColor = '#fee2e2';
statusPanel.style.borderColor = '#f87171';
statusPanel.innerText = `Error analyzing image: ${err.message}`;
}
return container;
}
Apply Changes