220 lines
8.8 KiB
Rust
220 lines
8.8 KiB
Rust
//! Image processing examples demonstrating all image enhancement features
|
|
|
|
use tvai::*;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|
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<dyn std::error::Error>> {
|
|
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<dyn std::error::Error>> {
|
|
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<dyn std::error::Error>> {
|
|
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<dyn std::error::Error>> {
|
|
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<dyn std::error::Error>> {
|
|
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);
|
|
})
|
|
}
|