improve ui

This commit is contained in:
Julian Freeman
2026-01-19 13:41:51 -04:00
parent d25f87abe0
commit 0cf429fff2
4 changed files with 40 additions and 10 deletions

View File

@@ -110,6 +110,7 @@ struct ZcaResult {
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
struct ExportImageTask { struct ExportImageTask {
path: String, path: String,
output_filename: Option<String>,
manual_position: Option<ManualPosition>, manual_position: Option<ManualPosition>,
scale: Option<f64>, scale: Option<f64>,
opacity: Option<f64>, opacity: Option<f64>,
@@ -251,7 +252,12 @@ async fn export_batch(images: Vec<ExportImageTask>, watermark: WatermarkSettings
} // END IF MODE == ADD } // END IF MODE == ADD
// Save // Save
let file_name = input_path.file_name().unwrap_or_default(); // Prioritize explicitly provided output filename (from original path), fall back to input filename
let file_name = match &task.output_filename {
Some(name) => std::ffi::OsStr::new(name),
None => input_path.file_name().unwrap_or_default()
};
let output_path = Path::new(&output_dir).join(file_name);
let output_path = Path::new(&output_dir).join(file_name); let output_path = Path::new(&output_dir).join(file_name);
// Handle format specific saving // Handle format specific saving

View File

@@ -50,13 +50,20 @@ async function exportBatch() {
isExporting.value = true; isExporting.value = true;
// Map images to include manual settings // Map images to include manual settings
const exportTasks = store.images.map(img => ({ const exportTasks = store.images.map(img => {
path: img.path, // Extract filename from originalPath to ensure export uses original name
manual_position: img.manualPosition || null, // Handles both Windows (\) and Unix (/) separators
scale: img.scale || null, const originalName = img.originalPath.split(/[/\\]/).pop() || "image.png";
opacity: img.opacity || null,
color: img.color || null return {
})); path: img.path,
output_filename: originalName,
manual_position: img.manualPosition || null,
scale: img.scale || null,
opacity: img.opacity || null,
color: img.color || null
};
});
// Pass dummy globals for rust struct compatibility // Pass dummy globals for rust struct compatibility
// The backend struct fields are named _manual_override and _manual_position // The backend struct fields are named _manual_override and _manual_position

View File

@@ -232,7 +232,12 @@ const applyAll = () => {
<div class="p-3 bg-red-900/20 border border-red-900/50 rounded text-xs text-red-200 flex flex-col gap-1"> <div class="p-3 bg-red-900/20 border border-red-900/50 rounded text-xs text-red-200 flex flex-col gap-1">
<span>AI 修复功能已就绪</span> <span>AI 修复功能已就绪</span>
<span v-if="store.isProcessing" class="text-yellow-300 animate-pulse">正在处理中请稍候...</span> <span v-if="store.isProcessing" class="text-yellow-300 animate-pulse">
正在处理: {{ store.progress.current }} / {{ store.progress.total }}
</span>
<span v-if="store.isDetecting" class="text-blue-300 animate-pulse">
正在检测: {{ store.progress.current }} / {{ store.progress.total }}
</span>
</div> </div>
<!-- Execution Controls --> <!-- Execution Controls -->

View File

@@ -54,6 +54,7 @@ export const useGalleryStore = defineStore("gallery", () => {
const isDetecting = ref(false); const isDetecting = ref(false);
const isProcessing = ref(false); const isProcessing = ref(false);
const progress = ref({ current: 0, total: 0 });
const selectedImage = computed(() => { const selectedImage = computed(() => {
if (selectedIndex.value >= 0 && selectedIndex.value < images.value.length) { if (selectedIndex.value >= 0 && selectedIndex.value < images.value.length) {
@@ -136,8 +137,10 @@ export const useGalleryStore = defineStore("gallery", () => {
async function detectCurrentWatermark() { async function detectCurrentWatermark() {
if (selectedIndex.value < 0 || !images.value[selectedIndex.value]) return; if (selectedIndex.value < 0 || !images.value[selectedIndex.value]) return;
isDetecting.value = true; isDetecting.value = true;
progress.value = { current: 0, total: 1 };
try { try {
await detectWatermarkForImage(images.value[selectedIndex.value]); await detectWatermarkForImage(images.value[selectedIndex.value]);
progress.value.current = 1;
} finally { } finally {
isDetecting.value = false; isDetecting.value = false;
} }
@@ -146,11 +149,15 @@ export const useGalleryStore = defineStore("gallery", () => {
async function detectAllWatermarks() { async function detectAllWatermarks() {
if (images.value.length === 0) return; if (images.value.length === 0) return;
isDetecting.value = true; isDetecting.value = true;
progress.value = { current: 0, total: images.value.length };
try { try {
const batchSize = 5; const batchSize = 5;
for (let i = 0; i < images.value.length; i += batchSize) { for (let i = 0; i < images.value.length; i += batchSize) {
const batch = images.value.slice(i, i + batchSize).map(img => detectWatermarkForImage(img)); const batch = images.value.slice(i, i + batchSize).map(async (img) => {
await detectWatermarkForImage(img);
progress.value.current++;
});
await Promise.all(batch); await Promise.all(batch);
} }
} finally { } finally {
@@ -211,8 +218,10 @@ export const useGalleryStore = defineStore("gallery", () => {
if (!img) return; if (!img) return;
isProcessing.value = true; isProcessing.value = true;
progress.value = { current: 0, total: 1 };
try { try {
await runInpaintingForImage(img); await runInpaintingForImage(img);
progress.value.current = 1;
} catch (e) { } catch (e) {
alert("处理失败: " + e); alert("处理失败: " + e);
} finally { } finally {
@@ -225,10 +234,12 @@ export const useGalleryStore = defineStore("gallery", () => {
if (candidates.length === 0) return; if (candidates.length === 0) return;
isProcessing.value = true; isProcessing.value = true;
progress.value = { current: 0, total: candidates.length };
try { try {
// Sequential processing to avoid freezing UI or overloading backend // Sequential processing to avoid freezing UI or overloading backend
for (const img of candidates) { for (const img of candidates) {
await runInpaintingForImage(img); await runInpaintingForImage(img);
progress.value.current++;
} }
alert("批量处理完成!"); alert("批量处理完成!");
} catch (e) { } catch (e) {
@@ -285,6 +296,7 @@ export const useGalleryStore = defineStore("gallery", () => {
brushSettings, brushSettings,
isDetecting, isDetecting,
isProcessing, isProcessing,
progress,
setImages, setImages,
selectImage, selectImage,
updateWatermarkSettings, updateWatermarkSettings,