Creation chat
ClarkZhang
please create a OCR tool page, user can upload an image, and the tool will extract the text from the image
02-25 09:00
暂无回复
No comments yet
登录 后可以评论
Assistant
(HTML code has been generated and updated; see above for the current version.)
This OCR tool page includes:
1. A clean, modern UI with responsive design that works on both mobile and desktop
2. Full dark/light mode support with theme toggle button
3. Image upload functionality with preview
4. Tesseract.js integration for client-side OCR processing
5. Progress tracking during OCR processing
6. Text extraction display with copy functionality
7. User-friendly instructions and notes
8. Error handling and user feedback
9. Console logging for debugging purposes
The tool works entirely in the browser - no images are uploaded to any server. It supports both Chinese and English text recognition. First-time language package loading may take longer, but subsequent uses will be faster.
To use the tool:
1. Upload an image using the drag-and-drop area or file selector
2. Wait for the OCR processing to complete (progress shown in real-time)
3. View the extracted text in the results area
4. Copy the text to your clipboard with the "Copy Text" button
The console in the bottom-right of the preview shows detailed logs of the OCR process. You can copy these logs and paste them back into the chat for debugging if needed.
▼ Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image to Text OCR Tool</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>tailwind.config = { darkMode: 'class' }</script>
</head>
<body class="min-h-screen bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100">
<!-- Theme toggle button -->
<button id="theme-toggle-btn" class="fixed top-4 right-4 z-10 p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors flex items-center justify-center" aria-label="Toggle theme" onclick="toggleTheme()">
<svg id="icon-moon" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998z"/></svg>
<svg id="icon-sun" class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg>
</button>
<script>
function toggleTheme(){ var el=document.documentElement; var isDark=!el.classList.contains('dark'); el.classList.toggle('dark',isDark); localStorage.setItem('theme',isDark?'dark':'light'); applyTheme(isDark); }
function applyTheme(isDark){ document.getElementById('icon-moon').style.display=isDark?'none':'block'; document.getElementById('icon-sun').style.display=isDark?'block':'none'; }
document.addEventListener('DOMContentLoaded',function(){ var saved=localStorage.getItem('theme'); var isDark=saved==='dark'||(!saved&&window.matchMedia('(prefers-color-scheme: dark)').matches); document.documentElement.classList.toggle('dark',isDark); applyTheme(isDark); });
</script>
<div class="container mx-auto px-4 py-12 max-w-4xl">
<header class="text-center mb-12">
<h1 class="text-3xl md:text-4xl font-bold text-slate-900 dark:text-slate-100 mb-3">Image to Text OCR Tool</h1>
<p class="text-lg text-slate-700 dark:text-slate-300 max-w-2xl mx-auto">
Upload an image and extract text from it using advanced OCR technology. Supports both Chinese and English.
</p>
</header>
<main>
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-lg p-6 mb-8 border border-slate-200 dark:border-slate-700">
<div class="mb-6">
<label class="block text-slate-700 dark:text-slate-300 font-medium mb-2" for="image-upload">
Upload Image
</label>
<div class="flex items-center justify-center w-full">
<label for="image-upload" class="flex flex-col items-center justify-center w-full h-64 border-2 border-dashed rounded-xl cursor-pointer border-slate-300 dark:border-slate-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors bg-slate-50 dark:bg-slate-700/50">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-10 h-10 mb-3 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<p class="mb-2 text-sm text-slate-500 dark:text-slate-400">
<span class="font-semibold">Click to upload</span> or drag and drop
</p>
<p class="text-xs text-slate-500 dark:text-slate-400">
PNG, JPG, JPEG (MAX. 10MB)
</p>
</div>
<input id="image-upload" type="file" class="hidden" accept="image/*" />
</label>
</div>
</div>
<div id="image-preview-container" class="hidden mb-6">
<h3 class="text-lg font-medium text-slate-800 dark:text-slate-200 mb-3">Image Preview</h3>
<div class="flex justify-center">
<img id="image-preview" src="" alt="Preview" class="max-h-64 rounded-lg shadow-md">
</div>
</div>
<div id="progress-container" class="hidden mb-6">
<h3 class="text-lg font-medium text-slate-800 dark:text-slate-200 mb-3">Processing Image</h3>
<div class="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-2.5">
<div id="progress-bar" class="bg-blue-600 dark:bg-blue-500 h-2.5 rounded-full" style="width: 0%"></div>
</div>
<p id="progress-status" class="text-slate-600 dark:text-slate-400 text-sm mt-2">Initializing OCR...</p>
</div>
<div id="result-container" class="hidden">
<div class="flex justify-between items-center mb-3">
<h3 class="text-lg font-medium text-slate-800 dark:text-slate-200">Extracted Text</h3>
<button id="copy-button" class="text-sm bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white px-3 py-1.5 rounded-lg transition-colors">
Copy Text
</button>
</div>
<div class="relative">
<textarea id="result-text" class="w-full h-48 p-4 bg-slate-50 dark:bg-slate-700 text-slate-800 dark:text-slate-200 border border-slate-300 dark:border-slate-600 rounded-lg resize-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" readonly></textarea>
</div>
</div>
</div>
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-lg p-6 border border-slate-200 dark:border-slate-700">
<h2 class="text-xl font-semibold text-slate-900 dark:text-slate-100 mb-4">How to Use This Tool</h2>
<ul class="space-y-3 text-slate-700 dark:text-slate-300">
<li class="flex items-start">
<span class="text-blue-600 dark:text-blue-400 font-bold mr-2">1.</span>
<span>Click the upload area or drag and drop an image file</span>
</li>
<li class="flex items-start">
<span class="text-blue-600 dark:text-blue-400 font-bold mr-2">2.</span>
<span>Wait for the OCR processing to complete (may take 10-30 seconds for first use)</span>
</li>
<li class="flex items-start">
<span class="text-blue-600 dark:text-blue-400 font-bold mr-2">3.</span>
<span>Review the extracted text in the result box</span>
</li>
<li class="flex items-start">
<span class="text-blue-600 dark:text-blue-400 font-bold mr-2">4.</span>
<span>Click "Copy Text" to copy the result to your clipboard</span>
</li>
</ul>
<div class="mt-4 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg">
<p class="text-amber-700 dark:text-amber-300 text-sm">
<span class="font-semibold">Note:</span> First-time language package loading may take longer. Subsequent uses will be faster.
</p>
</div>
</div>
</main>
<footer class="mt-12 text-center text-slate-600 dark:text-slate-400 text-sm">
<p>© 2023 OCR Text Extraction Tool. All processing happens in your browser - no images are uploaded to any server.</p>
</footer>
</div>
<!-- Custom modal for messages -->
<div id="custom-modal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 hidden" aria-hidden="true">
<div class="rounded-xl bg-white dark:bg-slate-800 p-6 shadow-xl max-w-sm w-full border border-slate-200 dark:border-slate-700">
<p id="custom-modal-msg" class="text-slate-700 dark:text-slate-200 mb-4"></p>
<button type="button" onclick="hideModal()" class="w-full rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">OK</button>
</div>
</div>
<script>
function showModal(msg){
var el=document.getElementById('custom-modal');
document.getElementById('custom-modal-msg').textContent=msg||'';
el.classList.remove('hidden');
}
function hideModal(){
document.getElementById('custom-modal').classList.add('hidden');
}
</script>
<!-- Tesseract.js for OCR -->
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js"></script>
<script>
// DOM Elements
const imageUpload = document.getElementById('image-upload');
const imagePreviewContainer = document.getElementById('image-preview-container');
const imagePreview = document.getElementById('image-preview');
const progressContainer = document.getElementById('progress-container');
const progressBar = document.getElementById('progress-bar');
const progressStatus = document.getElementById('progress-status');
const resultContainer = document.getElementById('result-container');
const resultText = document.getElementById('result-text');
const copyButton = document.getElementById('copy-button');
// Handle image upload
imageUpload.addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
// Validate file type
if (!file.type.match('image.*')) {
showModal('Please select a valid image file (PNG, JPG, JPEG)');
return;
}
// Preview image
const reader = new FileReader();
reader.onload = function(event) {
imagePreview.src = event.target.result;
imagePreviewContainer.classList.remove('hidden');
// Reset previous results
resultContainer.classList.add('hidden');
progressContainer.classList.add('hidden');
// Process image with OCR
processImageWithOCR(event.target.result);
};
reader.readAsDataURL(file);
});
// Process image with Tesseract.js
function processImageWithOCR(imageSrc) {
// Show progress container
progressContainer.classList.remove('hidden');
progressBar.style.width = '0%';
progressStatus.textContent = 'Initializing OCR...';
console.log('Starting OCR processing');
Tesseract.recognize(
imageSrc,
'chi_sim+eng', // Language for Chinese and English
{
logger: (m) => {
console.log('OCR Progress:', m);
if (m.status === 'loading tesseract core') {
progressStatus.textContent = 'Loading OCR engine...';
} else if (m.status === 'initializing api') {
progressStatus.textContent = 'Initializing OCR API...';
} else if (m.status === 'loading language traineddata') {
progressStatus.textContent = 'Loading language data (may take a moment for first use)...';
} else if (m.status === 'recognizing text') {
const progress = Math.min(99, Math.floor(m.progress * 100));
progressBar.style.width = `${progress}%`;
progressStatus.textContent = `Recognizing text... ${progress}%`;
}
}
}
).then(result => {
console.log('OCR completed successfully');
progressBar.style.width = '100%';
progressStatus.textContent = 'OCR completed!';
// Show results
resultText.value = result.data.text;
resultContainer.classList.remove('hidden');
// Hide progress after a delay
setTimeout(() => {
progressContainer.classList.add('hidden');
}, 1500);
}).catch(err => {
console.error('OCR Error:', err);
progressStatus.textContent = 'Error occurred during OCR processing';
showModal('OCR processing failed. Please try another image.');
});
}
// Copy text to clipboard
copyButton.addEventListener('click', function() {
resultText.select();
document.execCommand('copy');
// Show feedback
const originalText = copyButton.textContent;
copyButton.textContent = 'Copied!';
setTimeout(() => {
copyButton.textContent = originalText;
}, 2000);
});
</script>
</body>
</html>
02-25 09:02
暂无回复
No comments yet
登录 后可以评论
Comments
暂无回复
No comments yet
登录 后可以评论