//! Simple Local Image Upload and Enhancement //! //! A simplified version that focuses on the core functionality: //! 1. Upload a local image to ComfyUI server //! 2. Execute AI Model Face & Hair enhancement //! 3. Get the enhanced image URLs use std::collections::HashMap; use std::path::Path; use std::sync::Arc; use comfyui_sdk::{ ComfyUIClient, ComfyUIClientConfig, ExecutionOptions, AI_MODEL_FACE_HAIR_FIX_TEMPLATE }; use comfyui_sdk::utils::SimpleCallbacks; use serde_json::json; #[tokio::main] async fn main() -> Result<(), Box> { println!("šŸš€ Simple Local Image Enhancement Test"); // Configuration let server_url = "http://192.168.0.193:8188"; let image_path = "20250808-111737.png"; // Step 1: Initialize client and connect println!("šŸ“” Connecting to ComfyUI server at {}...", server_url); let mut client = ComfyUIClient::new(ComfyUIClientConfig { base_url: server_url.to_string(), ..Default::default() })?; client.connect().await?; println!("āœ… Connected!"); // Step 2: Register template println!("šŸ“ Registering AI enhancement template..."); client.templates().register_from_data(AI_MODEL_FACE_HAIR_FIX_TEMPLATE.clone())?; let template = client.templates_ref() .get_by_id("ai-model-face-hair-fix") .ok_or("Template not found")?; println!("āœ… Template ready!"); // Step 3: Check if image exists if !Path::new(image_path).exists() { println!("āŒ Image file not found: {}", image_path); println!("šŸ’” Please make sure the file exists in the current directory"); return Ok(()); } // Step 4: Upload image println!("šŸ“¤ Uploading image: {}...", image_path); let upload_response = client.upload_image(image_path, false).await?; println!("āœ… Upload successful! Server filename: {}", upload_response.name); // Step 5: Setup progress callbacks let callbacks = Arc::new( SimpleCallbacks::new() .with_progress(|progress| { let percentage = (progress.progress as f64 / progress.max as f64 * 100.0) as u32; println!("ā³ Progress: {}%", percentage); }) .with_executing(|node_id| { println!("šŸ”„ Processing node: {}", node_id); }) .with_error(|error| { println!("āŒ Error: {}", error.message); }) ); // Step 6: Execute enhancement println!("šŸŽØ Starting AI enhancement..."); let mut parameters = HashMap::new(); parameters.insert("input_image".to_string(), json!(upload_response.name)); parameters.insert("face_prompt".to_string(), json!("beautiful woman, perfect skin, detailed facial features")); parameters.insert("face_denoise".to_string(), json!("0.25")); let result = client.execute_template_with_callbacks( template, parameters, ExecutionOptions { timeout: Some(std::time::Duration::from_secs(180)), priority: None, }, callbacks, ).await?; // Step 7: Show results if result.success { println!("\nšŸŽ‰ Enhancement completed successfully!"); println!("ā±ļø Execution time: {:.1}s", result.execution_time as f64 / 1000.0); if let Some(outputs) = &result.outputs { let image_urls = client.outputs_to_urls(outputs); if !image_urls.is_empty() { println!("\nšŸ–¼ļø Enhanced image URLs:"); for (i, url) in image_urls.iter().enumerate() { println!(" {}. {}", i + 1, url); } println!("\nšŸ’” To view your enhanced image:"); println!(" - Copy the URL above and paste it in your browser"); println!(" - Right-click and 'Save As' to download the image"); } else { println!("āš ļø No image URLs found in outputs"); } } } else { println!("āŒ Enhancement failed!"); if let Some(error) = &result.error { println!("Error: {}", error.message); } } // Step 8: Cleanup client.disconnect().await?; println!("\nšŸ‘‹ Disconnected from server"); Ok(()) } /// Helper function to validate image file fn validate_image_file(path: &str) -> Result<(), String> { let path = Path::new(path); if !path.exists() { return Err(format!("File does not exist: {}", path.display())); } if !path.is_file() { return Err(format!("Path is not a file: {}", path.display())); } // Check file extension if let Some(extension) = path.extension() { let ext = extension.to_string_lossy().to_lowercase(); match ext.as_str() { "png" | "jpg" | "jpeg" | "bmp" | "tiff" | "webp" => Ok(()), _ => Err(format!("Unsupported image format: {}", ext)), } } else { Err("File has no extension".to_string()) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_validate_image_file() { // Test with non-existent file assert!(validate_image_file("non_existent.png").is_err()); // Test with valid extensions // Note: These tests would pass if the files existed // assert!(validate_image_file("test.png").is_ok()); // assert!(validate_image_file("test.jpg").is_ok()); } }