duqing2026's picture
init
8b1c497
Raw
History Blame Contribute Delete
9.65 kB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>批量图片处理工坊 - Batch Image Workshop</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.drop-zone {
border: 2px dashed #cbd5e1;
transition: all 0.3s ease;
}
.drop-zone.dragover {
border-color: #3b82f6;
background-color: #eff6ff;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen text-gray-800 font-sans">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- Header -->
<header class="text-center mb-10">
<h1 class="text-4xl font-bold text-gray-900 mb-2">
<i class="fas fa-images text-blue-500 mr-2"></i>批量图片处理工坊
</h1>
<p class="text-gray-600">
完全本地运行(CPU),隐私安全。支持批量缩放、格式转换、水印添加。
</p>
</header>
<form action="/process" method="POST" enctype="multipart/form-data" id="processForm" class="bg-white rounded-xl shadow-lg p-6 md:p-8">
<!-- Upload Section -->
<div class="mb-8">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<span class="bg-blue-100 text-blue-600 rounded-full w-8 h-8 flex items-center justify-center mr-3 text-sm">1</span>
上传图片
</h2>
<div id="dropZone" class="drop-zone rounded-lg p-10 text-center cursor-pointer hover:bg-gray-50">
<input type="file" name="files" id="fileInput" multiple accept="image/*" class="hidden">
<div class="space-y-3">
<i class="fas fa-cloud-upload-alt text-4xl text-gray-400"></i>
<div class="text-lg text-gray-600">点击或拖拽图片到这里</div>
<p class="text-sm text-gray-400" id="fileCount">支持 JPG, PNG, WEBP 等常见格式</p>
</div>
</div>
<div id="fileList" class="mt-4 flex flex-wrap gap-2 text-sm text-gray-600"></div>
</div>
<!-- Settings Section -->
<div class="mb-8">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<span class="bg-blue-100 text-blue-600 rounded-full w-8 h-8 flex items-center justify-center mr-3 text-sm">2</span>
处理选项
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Format -->
<div class="space-y-2">
<label class="block font-medium text-gray-700">目标格式</label>
<select name="target_format" class="w-full border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 p-2 border">
<option value="original">保持原格式</option>
<option value="jpeg">JPG / JPEG</option>
<option value="png">PNG</option>
<option value="webp">WEBP</option>
</select>
</div>
<!-- Resize -->
<div class="space-y-2">
<label class="block font-medium text-gray-700">调整大小</label>
<div class="flex gap-2">
<select name="resize_mode" id="resizeMode" class="w-1/2 border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 p-2 border">
<option value="none">不调整</option>
<option value="percentage">按百分比缩放</option>
<option value="width">固定宽度 (保持比例)</option>
</select>
<input type="number" name="resize_value" id="resizeValue" placeholder="100" class="w-1/2 border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 p-2 border hidden">
</div>
</div>
<!-- Watermark -->
<div class="space-y-2">
<label class="block font-medium text-gray-700">文字水印 (可选)</label>
<input type="text" name="watermark_text" placeholder="例如:@我的版权" class="w-full border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200 p-2 border">
</div>
<!-- Extras -->
<div class="space-y-2 flex items-center pt-6">
<label class="inline-flex items-center cursor-pointer">
<input type="checkbox" name="strip_exif" class="form-checkbox h-5 w-5 text-blue-600" checked>
<span class="ml-2 text-gray-700">清除 EXIF 信息 (隐私保护)</span>
</label>
</div>
</div>
</div>
<!-- Submit -->
<div class="text-center">
<button type="submit" id="submitBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-10 rounded-full shadow-lg transition duration-200 transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed">
<i class="fas fa-magic mr-2"></i>开始处理并下载
</button>
</div>
</form>
<footer class="mt-12 text-center text-gray-400 text-sm">
<p>&copy; 2026 Batch Image Workshop. Open Source Project.</p>
</footer>
</div>
<script>
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
const fileCount = document.getElementById('fileCount');
const resizeMode = document.getElementById('resizeMode');
const resizeValue = document.getElementById('resizeValue');
const processForm = document.getElementById('processForm');
const submitBtn = document.getElementById('submitBtn');
// Drag & Drop interactions
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
fileInput.files = e.dataTransfer.files;
updateFileList();
});
dropZone.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', updateFileList);
function updateFileList() {
const files = fileInput.files;
if (files.length > 0) {
fileCount.innerText = `已选择 ${files.length} 个文件`;
fileList.innerHTML = '';
// Only show first 5 names
Array.from(files).slice(0, 5).forEach(file => {
const span = document.createElement('span');
span.className = 'bg-gray-100 px-2 py-1 rounded border';
span.innerText = file.name;
fileList.appendChild(span);
});
if (files.length > 5) {
const more = document.createElement('span');
more.innerText = `... 等共 ${files.length} 个文件`;
fileList.appendChild(more);
}
} else {
fileCount.innerText = '支持 JPG, PNG, WEBP 等常见格式';
fileList.innerHTML = '';
}
}
// Resize inputs logic
resizeMode.addEventListener('change', () => {
if (resizeMode.value === 'none') {
resizeValue.classList.add('hidden');
} else {
resizeValue.classList.remove('hidden');
if (resizeMode.value === 'percentage') {
resizeValue.placeholder = '缩放比例 % (例如 50)';
resizeValue.value = 50;
} else {
resizeValue.placeholder = '目标宽度 px (例如 800)';
resizeValue.value = 800;
}
}
});
// Form Submit
processForm.addEventListener('submit', () => {
if (fileInput.files.length === 0) {
alert('请先上传图片!');
event.preventDefault();
return;
}
// Show loading state
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>处理中...';
submitBtn.disabled = true;
// Re-enable after a few seconds (since download doesn't trigger page reload)
setTimeout(() => {
submitBtn.innerHTML = '<i class="fas fa-magic mr-2"></i>开始处理并下载';
submitBtn.disabled = false;
}, 3000);
});
</script>
</body>
</html>