fix image type bug

This commit is contained in:
Julian Freeman
2026-01-20 22:08:56 -04:00
parent 52fb288bed
commit 0541dbfd69
6 changed files with 26 additions and 16 deletions

View File

@@ -3,5 +3,5 @@
Generated by Gemini Generated by Gemini
Models: Models:
LaMa: https://huggingface.co/Carve/LaMa-ONNX/blob/main/lama_fp32.onnx - LaMa: https://huggingface.co/Carve/LaMa-ONNX/blob/main/lama_fp32.onnx
en_PP-OCRv3_det_infer: https://huggingface.co/SWHL/RapidOCR/blob/main/PP-OCRv4/en_PP-OCRv3_det_infer.onnx - en_PP-OCRv3_det_infer: https://huggingface.co/SWHL/RapidOCR/blob/main/PP-OCRv4/en_PP-OCRv3_det_infer.onnx

View File

@@ -1,7 +1,7 @@
{ {
"name": "watermark-wizard", "name": "watermark-wizard",
"private": true, "private": true,
"version": "1.0.0", "version": "1.0.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

2
src-tauri/Cargo.lock generated
View File

@@ -5117,7 +5117,7 @@ dependencies = [
[[package]] [[package]]
name = "watermark-wizard" name = "watermark-wizard"
version = "1.0.0" version = "1.0.1"
dependencies = [ dependencies = [
"ab_glyph", "ab_glyph",
"image", "image",

View File

@@ -1,8 +1,8 @@
[package] [package]
name = "watermark-wizard" name = "watermark-wizard"
version = "1.0.0" version = "1.0.1"
description = "A Tauri App handles watermarks" description = "A Tauri App handles watermarks"
authors = ["you"] authors = ["Julian"]
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -19,6 +19,14 @@ fn get_cache_dir() -> std::path::PathBuf {
path path
} }
fn load_image_safe(path: &Path) -> Result<image::DynamicImage, String> {
let bytes = fs::read(path).map_err(|e| {
let exists = path.exists();
format!("读取文件失败 (存在: {}) / Failed to read file '{}': {}", exists, path.to_string_lossy(), e)
})?;
image::load_from_memory(&bytes).map_err(|e| format!("图片解码失败 / Failed to decode image '{}': {}", path.to_string_lossy(), e))
}
fn generate_thumbnail(original_path: &Path) -> Option<String> { fn generate_thumbnail(original_path: &Path) -> Option<String> {
let cache_dir = get_cache_dir(); let cache_dir = get_cache_dir();
@@ -35,7 +43,7 @@ fn generate_thumbnail(original_path: &Path) -> Option<String> {
} }
// Generate // Generate
if let Ok(img) = image::open(original_path) { if let Ok(img) = load_image_safe(original_path) {
let thumb = img.thumbnail(u32::MAX, 200); let thumb = img.thumbnail(u32::MAX, 200);
let _file = fs::File::create(&thumb_path).ok()?; let _file = fs::File::create(&thumb_path).ok()?;
thumb.save_with_format(&thumb_path, image::ImageFormat::Jpeg).ok()?; thumb.save_with_format(&thumb_path, image::ImageFormat::Jpeg).ok()?;
@@ -153,9 +161,11 @@ async fn export_batch(images: Vec<ExportImageTask>, watermark: WatermarkSettings
let results: Vec<Result<(), String>> = images.par_iter().map(|task| { let results: Vec<Result<(), String>> = images.par_iter().map(|task| {
let input_path = Path::new(&task.path); let input_path = Path::new(&task.path);
let img_result = image::open(input_path);
if let Ok(dynamic_img) = img_result { // Use safe loading helper
let img_result = load_image_safe(input_path);
if let Ok(dynamic_img) = &img_result {
let mut base_img = dynamic_img.to_rgba8(); let mut base_img = dynamic_img.to_rgba8();
let (width, height) = base_img.dimensions(); let (width, height) = base_img.dimensions();
@@ -277,7 +287,7 @@ async fn export_batch(images: Vec<ExportImageTask>, watermark: WatermarkSettings
Ok(()) Ok(())
} else { } else {
Err(format!("Failed to open {}", task.path)) Err(img_result.unwrap_err())
} }
}).collect(); }).collect();
@@ -386,7 +396,7 @@ fn calculate_zca_internal(img: &image::DynamicImage) -> Result<ZcaResult, String
#[tauri::command] #[tauri::command]
fn get_zca_suggestion(path: String) -> Result<ZcaResult, String> { fn get_zca_suggestion(path: String) -> Result<ZcaResult, String> {
let img = image::open(&path).map_err(|e| e.to_string())?; let img = load_image_safe(Path::new(&path))?;
calculate_zca_internal(&img) calculate_zca_internal(&img)
} }
@@ -399,7 +409,7 @@ struct LayoutResult {
#[tauri::command] #[tauri::command]
async fn layout_watermark(path: String, text: String, base_scale: f64) -> Result<LayoutResult, String> { async fn layout_watermark(path: String, text: String, base_scale: f64) -> Result<LayoutResult, String> {
let img = image::open(&path).map_err(|e| e.to_string())?; let img = load_image_safe(Path::new(&path))?;
let (width, height) = img.dimensions(); let (width, height) = img.dimensions();
let font = FontRef::try_from_slice(FONT_DATA).map_err(|e| format!("Font error: {}", e))?; let font = FontRef::try_from_slice(FONT_DATA).map_err(|e| format!("Font error: {}", e))?;
@@ -468,7 +478,7 @@ struct Rect {
#[tauri::command] #[tauri::command]
async fn detect_watermark(app: AppHandle, path: String) -> Result<DetectionResult, String> { async fn detect_watermark(app: AppHandle, path: String) -> Result<DetectionResult, String> {
let img = image::open(&path).map_err(|e| e.to_string())?.to_rgba8(); let img = load_image_safe(Path::new(&path))?.to_rgba8();
// 1. Try OCR Detection // 1. Try OCR Detection
let ocr_model_path = app.path().resource_dir() let ocr_model_path = app.path().resource_dir()
@@ -662,7 +672,7 @@ enum MaskStroke {
#[tauri::command] #[tauri::command]
async fn run_inpainting(app: AppHandle, path: String, strokes: Vec<MaskStroke>) -> Result<String, String> { async fn run_inpainting(app: AppHandle, path: String, strokes: Vec<MaskStroke>) -> Result<String, String> {
let img = image::open(&path).map_err(|e| e.to_string())?.to_rgba8(); let img = load_image_safe(Path::new(&path))?.to_rgba8();
let (width, height) = img.dimensions(); let (width, height) = img.dimensions();
// 1. Create Gray Mask (0 = keep, 255 = remove) // 1. Create Gray Mask (0 = keep, 255 = remove)

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "watermark-wizard", "productName": "watermark-wizard",
"version": "1.0.0", "version": "1.0.1",
"identifier": "top.volan.watermark-wizard", "identifier": "top.volan.watermark-wizard",
"build": { "build": {
"beforeDevCommand": "pnpm dev", "beforeDevCommand": "pnpm dev",
@@ -12,7 +12,7 @@
"app": { "app": {
"windows": [ "windows": [
{ {
"title": "水印精灵 v1.0.0", "title": "水印精灵 v1.0.1",
"width": 1650, "width": 1650,
"height": 1000 "height": 1000
} }