//! Image processing examples demonstrating all image enhancement features use tvai::*; #[tokio::main] async fn main() -> std::result::Result<(), Box> { println!("Topaz Video AI Library - Image Processing Examples"); // Detect Topaz installation if let Some(topaz_path) = detect_topaz_installation() { println!("Found Topaz Video AI at: {}", topaz_path.display()); // Create configuration let config = TvaiConfig::builder() .topaz_path(topaz_path) .use_gpu(true) .build()?; // Create processor let mut processor = TvaiProcessor::new(config)?; println!("Processor created successfully"); // Demonstrate image upscaling demonstrate_image_upscaling(&mut processor).await?; // Demonstrate batch processing demonstrate_batch_processing(&mut processor).await?; // Demonstrate format conversion demonstrate_format_conversion(&mut processor).await?; // Demonstrate image enhancement demonstrate_image_enhancement(&mut processor).await?; // Demonstrate quick functions demonstrate_quick_functions().await?; println!("All image processing examples completed successfully!"); } else { println!("Topaz Video AI not found. Please install it first."); } Ok(()) } async fn demonstrate_image_upscaling(processor: &mut TvaiProcessor) -> std::result::Result<(), Box> { println!("\n=== Image Upscaling Demo ==="); // Create upscaling parameters for different scenarios let scenarios = vec![ ("Photo Enhancement", ImageUpscaleParams::for_photo()), ("Artwork Upscaling", ImageUpscaleParams::for_artwork()), ("Screenshot Enhancement", ImageUpscaleParams::for_screenshot()), ("Portrait Enhancement", ImageUpscaleParams::for_portrait()), ("Custom Parameters", ImageUpscaleParams { scale_factor: 3.0, model: UpscaleModel::Ghq5, compression: -0.2, blend: 0.0, output_format: ImageFormat::Tiff, }), ]; for (name, params) in scenarios { println!("Scenario: {}", name); println!(" Model: {} ({})", params.model.as_str(), params.model.description()); println!(" Scale: {}x", params.scale_factor); println!(" Compression: {}", params.compression); println!(" Blend: {}", params.blend); println!(" Output Format: {}", params.output_format.extension().to_uppercase()); // In a real scenario, you would call: // let result = processor.upscale_image(input, output, params, Some(&progress_callback)).await?; // println!(" Processing time: {:?}", result.processing_time); } Ok(()) } async fn demonstrate_batch_processing(processor: &mut TvaiProcessor) -> std::result::Result<(), Box> { println!("\n=== Batch Processing Demo ==="); println!("Batch Image Upscaling:"); println!(" - Process multiple images at once"); println!(" - Consistent parameters across all images"); println!(" - Progress tracking for entire batch"); println!(" - Automatic output filename generation"); // In a real scenario: // let input_paths = vec![Path::new("image1.jpg"), Path::new("image2.png")]; // let params = ImageUpscaleParams::for_photo(); // let results = processor.batch_upscale_images(&input_paths, output_dir, params, Some(&progress_callback)).await?; // println!(" Processed {} images", results.len()); println!("\nDirectory Processing:"); println!(" - Auto-discover images in directory"); println!(" - Support for recursive subdirectory scanning"); println!(" - Filter by supported image formats"); println!(" - Batch process all discovered images"); // In a real scenario: // let results = processor.upscale_directory(input_dir, output_dir, params, true, Some(&progress_callback)).await?; // println!(" Processed {} images from directory", results.len()); Ok(()) } async fn demonstrate_format_conversion(processor: &mut TvaiProcessor) -> std::result::Result<(), Box> { println!("\n=== Format Conversion Demo ==="); let formats = vec![ (ImageFormat::Png, "Lossless compression, transparency support"), (ImageFormat::Jpg, "Lossy compression, smaller file size"), (ImageFormat::Tiff, "Professional format, lossless compression"), (ImageFormat::Bmp, "Uncompressed format, large file size"), ]; for (format, description) in formats { println!("Format: {} - {}", format.extension().to_uppercase(), description); println!(" FFmpeg format: {}", format.ffmpeg_format()); // In a real scenario: // let result = processor.convert_image_format(input, output, format, 95, Some(&progress_callback)).await?; // println!(" Conversion time: {:?}", result.processing_time); } println!("\nBatch Format Conversion:"); println!(" - Convert multiple images to same format"); println!(" - Configurable quality settings"); println!(" - Preserve original filenames"); // In a real scenario: // let input_paths = vec![/* image paths */]; // let results = processor.batch_convert_images(&input_paths, output_dir, ImageFormat::Png, 95, Some(&progress_callback)).await?; Ok(()) } async fn demonstrate_image_enhancement(processor: &mut TvaiProcessor) -> std::result::Result<(), Box> { println!("\n=== Image Enhancement Demo ==="); println!("Traditional Resize (Non-AI):"); println!(" - Fast geometric scaling"); println!(" - Maintain aspect ratio option"); println!(" - Multiple output formats"); println!(" - Good for simple size adjustments"); // In a real scenario: // let result = processor.resize_image(input, output, 1920, 1080, true, ImageFormat::Png, Some(&progress_callback)).await?; println!("\nAI-Powered Upscaling:"); println!(" - Machine learning enhancement"); println!(" - Detail reconstruction"); println!(" - Artifact reduction"); println!(" - Superior quality for enlargement"); println!("\nModel Comparison:"); let models = vec![ (UpscaleModel::Iris3, "Best general purpose model"), (UpscaleModel::Nyx3, "Optimized for portraits"), (UpscaleModel::Thf4, "Old content restoration"), (UpscaleModel::Ghq5, "Game/CG content"), (UpscaleModel::Prob4, "Problem content repair"), ]; for (model, description) in models { println!(" {}: {}", model.as_str(), description); if let Some(scale) = model.forces_scale() { println!(" (Forces {}x scale)", scale); } } Ok(()) } async fn demonstrate_quick_functions() -> std::result::Result<(), Box> { println!("\n=== Quick Functions Demo ==="); println!("Quick Image Upscale:"); println!(" - One-line image upscaling"); println!(" - Automatic Topaz detection"); println!(" - Default high-quality settings"); println!(" - Usage: quick_upscale_image(input, output, 2.0).await?"); println!("\nAuto Enhance Image:"); println!(" - Intelligent enhancement detection"); println!(" - Automatic parameter selection"); println!(" - Based on image characteristics"); println!(" - Usage: auto_enhance_image(input, output).await?"); println!("\nBatch Directory Processing:"); println!(" - Process entire directories"); println!(" - Recursive subdirectory support"); println!(" - Automatic file discovery"); println!(" - Usage: batch_upscale_directory(input_dir, output_dir, 2.0, true).await?"); println!("\nFormat Conversion:"); println!(" - Simple format conversion"); println!(" - Quality control"); println!(" - No AI processing needed"); println!(" - Usage: convert_image(input, output, ImageFormat::Png, 95).await?"); // In a real scenario, you would call these functions: // let result = quick_upscale_image(Path::new("input.jpg"), Path::new("output.png"), 2.0).await?; // let result = auto_enhance_image(Path::new("input.jpg"), Path::new("enhanced.png")).await?; // let results = batch_upscale_directory(Path::new("input_dir"), Path::new("output_dir"), 2.0, true).await?; // let result = convert_image(Path::new("input.jpg"), Path::new("output.png"), ImageFormat::Png, 95).await?; Ok(()) } // Progress callback example fn create_progress_callback(operation_name: &str) -> ProgressCallback { let name = operation_name.to_string(); Box::new(move |progress| { let percentage = (progress * 100.0) as u32; println!("{}: {}%", name, percentage); }) }