🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Traitement d'Images Web Rust
Exemples de traitement d'images Web Rust incluant lecture/écriture, redimensionnement et conversion de format
💻 Lecture/Écriture d'Image rust
🟢 simple
⭐⭐
Lire et enregistrer des fichiers image en utilisant le crate image
⏱️ 20 min
🏷️ rust, web, image processing
Prerequisites:
Basic Rust, image crate
// Web Rust Image Read/Save Examples
// Basic image file operations
//
// Add to Cargo.toml:
// [dependencies]
// image = "0.24"
use image::{DynamicImage, ImageError, io::Reader as ImageReader};
use std::path::Path;
// 1. Read Image
/// Read image from file path
fn read_image(path: &str) -> Result<DynamicImage, ImageError> {
let img = ImageReader::open(path)?.decode()?;
Ok(img)
}
/// Read image from bytes
fn read_image_from_bytes(data: &[u8]) -> Result<DynamicImage, ImageError> {
let img = image::load_from_memory(data)?;
Ok(img)
}
/// Read image with format hint
fn read_image_with_format(path: &str, format: image::ImageFormat) -> Result<DynamicImage, ImageError> {
let img = ImageReader::with_format(std::fs::File::open(path)?, format).decode()?;
Ok(img)
}
// 2. Save Image
/// Save image to file (auto-detect format from extension)
fn save_image(img: &DynamicImage, path: &str) -> Result<(), ImageError> {
img.save(path)?;
Ok(())
}
/// Save image with specific format
fn save_image_with_format(img: &DynamicImage, path: &str, format: image::ImageFormat) -> Result<(), ImageError> {
img.save_with_format(path, format)?;
Ok(())
}
/// Save image with quality (for JPEG)
fn save_image_jpeg_quality(img: &DynamicImage, path: &str, quality: u8) -> Result<(), ImageError> {
let encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(
&mut std::fs::File::create(path)?,
quality
);
img.write_with_encoder(encoder)?;
Ok(())
}
// 3. Image Information
/// Get image dimensions
fn get_image_dimensions(img: &DynamicImage) -> (u32, u32) {
img.dimensions()
}
/// Get image color type
fn get_image_color_type(img: &DynamicImage) -> String {
format!("{:?}", img.color())
}
/// Get image file size
fn get_image_file_size(path: &str) -> Result<u64, std::io::Error> {
Ok(std::fs::metadata(path)?.len())
}
// 4. Batch Operations
/// Read multiple images
fn read_multiple_images(paths: &[&str]) -> Vec<Result<DynamicImage, ImageError>> {
paths.iter().map(|&path| read_image(path)).collect()
}
/// Save multiple images
fn save_multiple_images(images: &[(&DynamicImage, &str)]) -> Vec<Result<(), ImageError>> {
images.iter().map(|(img, path)| save_image(img, path)).collect()
}
// 5. Image Validation
/// Check if file is valid image
fn is_valid_image(path: &str) -> bool {
ImageReader::open(path).is_ok() && ImageReader::open(path).and_then(|r| r.decode()).is_ok()
}
/// Get supported formats for a file
fn get_image_format(path: &str) -> Option<image::ImageFormat> {
Path::new(path)
.extension()
.and_then(|ext| ext.to_str())
.and_then(|ext| image::ImageFormat::from_extension(ext))
}
// 6. Create Basic Images
/// Create new blank image
fn create_blank_image(width: u32, height: u32, color: [u8; 3]) -> DynamicImage {
image::RgbImage::new(width, height).into()
}
/// Create solid color image
fn create_solid_color_image(width: u32, height: u32, r: u8, g: u8, b: u8) -> DynamicImage {
let img: image::RgbImage = image::RgbImage::from_fn(width, height, |_, _| {
image::Rgb([r, g, b])
});
img.into()
}
// 7. Image from Raw Data
/// Create image from raw RGB bytes
fn image_from_rgb_bytes(data: &[u8], width: u32, height: u32) -> Result<DynamicImage, ImageError> {
let img: image::RgbImage = image::RgbImage::from_raw(width, height, data.to_vec())
.ok_or(ImageError::Parameter(ErrorKind::DimensionError))?;
Ok(img.into())
}
/// Create image from raw RGBA bytes
fn image_from_rgba_bytes(data: &[u8], width: u32, height: u32) -> Result<DynamicImage, ImageError> {
let img: image::RgbaImage = image::RgbaImage::from_raw(width, height, data.to_vec())
.ok_or(ImageError::Parameter(ErrorKind::DimensionError))?;
Ok(img.into())
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Image Read/Save Examples ===\n");
// 1. Create a test image
println!("--- 1. Create Test Image ---");
let test_img = create_solid_color_image(200, 200, 100, 150, 200);
save_image(&test_img, "test_output.png")?;
println!("Created and saved test image");
// 2. Read image
println!("
--- 2. Read Image ---");
let img = read_image("test_output.png")?;
let (width, height) = get_image_dimensions(&img);
println!("Image dimensions: {}x{}", width, height);
println!("Color type: {}", get_image_color_type(&img));
// 3. Save in different formats
println!("
--- 3. Save in Different Formats ---");
save_image_with_format(&img, "output.jpg", image::ImageFormat::Jpeg)?;
save_image_with_format(&img, "output.bmp", image::ImageFormat::Bmp)?;
save_image_with_format(&img, "output.png", image::ImageFormat::Png)?;
println!("Saved in JPG, BMP, and PNG formats");
// 4. JPEG quality
println!("
--- 4. JPEG Quality ---");
save_image_jpeg_quality(&img, "output_high.jpg", 90)?;
save_image_jpeg_quality(&img, "output_low.jpg", 30)?;
println!("Saved high and low quality JPEGs");
// 5. File sizes
println!("
--- 5. File Sizes ---");
println!("PNG: {} bytes", get_image_file_size("output.png")?);
println!("JPEG (high): {} bytes", get_image_file_size("output_high.jpg")?);
println!("JPEG (low): {} bytes", get_image_file_size("output_low.jpg")?);
// 6. Read from bytes
println!("
--- 6. Read from Bytes ---");
let bytes = std::fs::read("test_output.png")?;
let img_from_bytes = read_image_from_bytes(&bytes)?;
println!("Read image from {} bytes", bytes.len());
// 7. Validation
println!("
--- 7. Validation ---");
println!("test_output.png is valid: {}", is_valid_image("test_output.png"));
println!("Format: {:?}", get_image_format("test_output.png"));
println!("
=== All Image Read/Save Examples Completed ===");
Ok(())
}
💻 Redimensionnement d'Image rust
🟡 intermediate
⭐⭐⭐
Redimensionner et mettre à l'échelle des images en utilisant diverses méthodes d'interpolation
⏱️ 25 min
🏷️ rust, web, image processing
Prerequisites:
Intermediate Rust, image crate
// Web Rust Image Scaling Examples
// Image resizing and scaling operations
//
// Add to Cargo.toml:
// [dependencies]
// image = "0.24"
use image::{DynamicImage, imageops, FilterType};
// 1. Basic Resizing
/// Resize image to exact dimensions
fn resize_exact(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize(width, height, FilterType::Lanczos3)
}
/// Resize maintaining aspect ratio
fn resize_aspect_ratio(img: &DynamicImage, max_width: u32, max_height: u32) -> DynamicImage {
img.resize(max_width, max_height, FilterType::Lanczos3)
}
/// Resize to fit within bounds
fn resize_to_fit(img: &DynamicImage, max_width: u32, max_height: u32) -> DynamicImage {
img.resize(max_width, max_height, FilterType::Lanczos3)
}
// 2. Advanced Scaling
/// Scale by factor
fn scale_by_factor(img: &DynamicImage, factor: f32) -> DynamicImage {
let (width, height) = img.dimensions();
let new_width = (width as f32 * factor) as u32;
let new_height = (height as f32 * factor) as u32;
img.resize(new_width, new_height, FilterType::Lanczos3)
}
/// Scale to width (maintain aspect ratio)
fn scale_to_width(img: &DynamicImage, target_width: u32) -> DynamicImage {
let (width, height) = img.dimensions();
let ratio = target_width as f32 / width as f32;
let new_height = (height as f32 * ratio) as u32;
img.resize(target_width, new_height, FilterType::Lanczos3)
}
/// Scale to height (maintain aspect ratio)
fn scale_to_height(img: &DynamicImage, target_height: u32) -> DynamicImage {
let (width, height) = img.dimensions();
let ratio = target_height as f32 / height as f32;
let new_width = (width as f32 * ratio) as u32;
img.resize(new_width, target_height, FilterType::Lanczos3)
}
// 3. Thumbnail Generation
/// Generate thumbnail
fn generate_thumbnail(img: &DynamicImage, size: u32) -> DynamicImage {
img.thumbnail(size, size)
}
/// Generate thumbnail with exact dimensions (crop if needed)
fn generate_thumbnail_exact(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize_exact(width, height, FilterType::Lanczos3)
}
/// Generate thumbnail with padding
fn generate_thumbnail_pad(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize_to_fill(width, height, FilterType::Lanczos3)
}
// 4. Filter Types
/// Resize with nearest neighbor (fast, low quality)
fn resize_nearest(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize(width, height, FilterType::Nearest)
}
/// Resize with triangle (moderate quality)
fn resize_triangle(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize(width, height, FilterType::Triangle)
}
/// Resize with Gaussian (smooth)
fn resize_gaussian(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize(width, height, FilterType::Gaussian)
}
/// Resize with CatmullRom (sharp)
fn resize_catmull(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
img.resize(width, height, FilterType::CatmullRom)
}
// 5. Special Scaling Operations
/// Resize to fit width, keeping aspect ratio
fn resize_fit_width(img: &DynamicImage, target_width: u32) -> DynamicImage {
scale_to_width(img, target_width)
}
/// Resize to fit height, keeping aspect ratio
fn resize_fit_height(img: &DynamicImage, target_height: u32) -> DynamicImage {
scale_to_height(img, target_height)
}
/// Resize and crop to exact dimensions
fn resize_crop(img: &DynamicImage, width: u32, height: u32) -> DynamicImage {
let (orig_width, orig_height) = img.dimensions();
// Calculate aspect ratios
let orig_ratio = orig_width as f32 / orig_height as f32;
let target_ratio = width as f32 / height as f32;
if orig_ratio > target_ratio {
// Crop width
let new_height = ((orig_width as f32 / target_ratio) as u32).min(orig_height);
let cropped = img.crop(
0,
(orig_height - new_height) / 2,
orig_width,
new_height
);
cropped.resize(width, height, FilterType::Lanczos3)
} else {
// Crop height
let new_width = ((orig_height as f32 * target_ratio) as u32).min(orig_width);
let cropped = img.crop(
(orig_width - new_width) / 2,
0,
new_width,
orig_height
);
cropped.resize(width, height, FilterType::Lanczos3)
}
}
// 6. Batch Resizing
/// Resize multiple images to same size
fn resize_batch(images: &[&DynamicImage], width: u32, height: u32) -> Vec<DynamicImage> {
images.iter().map(|img| resize_exact(img, width, height)).collect()
}
/// Create multiple sizes from one image
fn create_multiple_sizes(img: &DynamicImage, sizes: &[u32]) -> Vec<(u32, DynamicImage)> {
sizes.iter().map(|&size| {
(size, generate_thumbnail(img, size))
}).collect()
}
// 7. Smart Resizing
/// Resize with max dimension (maintain aspect ratio)
fn resize_max_dimension(img: &DynamicImage, max_dim: u32) -> DynamicImage {
let (width, height) = img.dimensions();
if width > height {
scale_to_width(img, max_dim)
} else {
scale_to_height(img, max_dim)
}
}
/// Resize with min dimension (maintain aspect ratio)
fn resize_min_dimension(img: &DynamicImage, min_dim: u32) -> DynamicImage {
let (width, height) = img.dimensions();
if width < height {
scale_to_width(img, min_dim)
} else {
scale_to_height(img, min_dim)
}
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Image Scaling Examples ===\n");
// Create test image
use image::RgbImage;
let test_img: DynamicImage = RgbImage::from_fn(800, 600, |x, y| {
let r = ((x as f32 / 800.0) * 255.0) as u8;
let g = ((y as f32 / 600.0) * 255.0) as u8;
let b = 128;
image::Rgb([r, g, b])
}).into();
println!("Original: {}x{}", test_img.width(), test_img.height());
// 1. Basic resize
println!("
--- 1. Basic Resize ---");
let resized = resize_exact(&test_img, 400, 300);
println!("Resized to: {}x{}", resized.width(), resized.height());
// 2. Scale to width
println!("
--- 2. Scale to Width ---");
let scaled_width = scale_to_width(&test_img, 300);
println!("Scaled to width 300: {}x{}", scaled_width.width(), scaled_width.height());
// 3. Scale to height
println!("
--- 3. Scale to Height ---");
let scaled_height = scale_to_height(&test_img, 200);
println!("Scaled to height 200: {}x{}", scaled_height.width(), scaled_height.height());
// 4. Scale by factor
println!("
--- 4. Scale by Factor ---");
let scaled_down = scale_by_factor(&test_img, 0.5);
let scaled_up = scale_by_factor(&test_img, 1.5);
println!("Scaled by 0.5: {}x{}", scaled_down.width(), scaled_down.height());
println!("Scaled by 1.5: {}x{}", scaled_up.width(), scaled_up.height());
// 5. Thumbnails
println!("
--- 5. Thumbnails ---");
let thumb = generate_thumbnail(&test_img, 150);
println!("Thumbnail 150x150: {}x{}", thumb.width(), thumb.height());
// 6. Different filters
println!("
--- 6. Different Filters ---");
let nearest = resize_nearest(&test_img, 200, 150);
let lanczos = resize_exact(&test_img, 200, 150);
println!("Nearest: {}x{}", nearest.width(), nearest.height());
println!("Lanczos: {}x{}", lanczos.width(), lanczos.height());
// 7. Multiple sizes
println!("
--- 7. Multiple Sizes ---");
let sizes = create_multiple_sizes(&test_img, &[50, 100, 150, 200, 300]);
for (size, img) in sizes {
println!("Size {}: {}x{}", size, img.width(), img.height());
}
// 8. Smart resizing
println!("
--- 8. Smart Resizing ---");
let max_dim = resize_max_dimension(&test_img, 400);
let min_dim = resize_min_dimension(&test_img, 300);
println!("Max dimension 400: {}x{}", max_dim.width(), max_dim.height());
println!("Min dimension 300: {}x{}", min_dim.width(), min_dim.height());
// 9. Resize and crop
println!("
--- 9. Resize and Crop ---");
let cropped = resize_crop(&test_img, 300, 300);
println!("Cropped to square: {}x{}", cropped.width(), cropped.height());
println!("
=== All Image Scaling Examples Completed ===");
Ok(())
}
💻 Conversion de Format d'Image rust
🟡 intermediate
⭐⭐⭐
Convertir entre différents formats d'image comme JPG, PNG, BMP, WebP
⏱️ 20 min
🏷️ rust, web, image processing
Prerequisites:
Intermediate Rust, image crate
// Web Rust Image Format Conversion Examples
// Convert images between different formats
//
// Add to Cargo.toml:
// [dependencies]
// image = "0.24"
use image::{DynamicImage, ImageFormat, DynamicImage::*};
use std::path::Path;
// 1. Basic Format Conversion
/// Convert image to different format
fn convert_format(img: &DynamicImage, output_path: &str, format: ImageFormat) -> Result<(), image::ImageError> {
img.save_with_format(output_path, format)?;
Ok(())
}
/// Convert with automatic format detection
fn convert_auto_format(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save(output_path)?;
Ok(())
}
/// Convert PNG to JPEG
fn png_to_jpeg(input_path: &str, output_path: &str) -> Result<(), image::ImageError> {
let img = image::open(input_path)?;
img.save_with_format(output_path, ImageFormat::Jpeg)?;
Ok(())
}
/// Convert JPEG to PNG
fn jpeg_to_png(input_path: &str, output_path: &str) -> Result<(), image::ImageError> {
let img = image::open(input_path)?;
img.save_with_format(output_path, ImageFormat::Png)?;
Ok(())
}
// 2. Conversion with Options
/// Convert to JPEG with quality
fn to_jpeg_with_quality(img: &DynamicImage, output_path: &str, quality: u8) -> Result<(), image::ImageError> {
let mut output = std::fs::File::create(output_path)?;
let encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut output, quality);
img.write_with_encoder(encoder)?;
Ok(())
}
/// Convert to PNG with compression
fn to_png_with_compression(img: &DynamicImage, output_path: &str, compression: image::codecs::png::CompressionType) -> Result<(), image::ImageError> {
let mut output = std::fs::File::create(output_path)?;
let encoder = image::codecs::png::PngEncoder::new_with_compression(&mut output, compression);
img.write_with_encoder(encoder)?;
Ok(())
}
/// Convert to PPM
fn to_ppm(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save_with_format(output_path, ImageFormat::Pnm)?;
Ok(())
}
// 3. Batch Conversion
/// Convert multiple images to same format
fn convert_batch(input_paths: &[&str], output_dir: &str, format: ImageFormat) -> Result<Vec<Result<(), image::ImageError>>, std::io::Error> {
std::fs::create_dir_all(output_dir)?;
Ok(input_paths.iter().map(|path| {
let img = image::open(path);
match img {
Ok(img) => {
let filename = Path::new(path).file_stem().unwrap().to_str().unwrap();
let ext = extension_from_format(format);
let output_path = format!("{}/{}.{}", output_dir, filename, ext);
convert_format(&img, &output_path, format)
},
Err(e) => Err(e)
}
}).collect())
}
/// Get file extension from format
fn extension_from_format(format: ImageFormat) -> &'static str {
match format {
ImageFormat::Png => "png",
ImageFormat::Jpeg => "jpg",
ImageFormat::Bmp => "bmp",
ImageFormat::WebP => "webp",
_ => "png"
}
}
// 4. Format-Specific Conversions
/// Convert to BMP (lossless)
fn to_bmp(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save_with_format(output_path, ImageFormat::Bmp)?;
Ok(())
}
/// Convert to WebP if available
fn to_webp(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save_with_format(output_path, ImageFormat::WebP)?;
Ok(())
}
/// Convert to ICO
fn to_ico(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save_with_format(output_path, ImageFormat::Ico)?;
Ok(())
}
/// Convert to TIFF
fn to_tiff(img: &DynamicImage, output_path: &str) -> Result<(), image::ImageError> {
img.save_with_format(output_path, ImageFormat::Tiff)?;
Ok(())
}
// 5. Color Space Conversions
/// Convert to grayscale
fn to_grayscale(img: &DynamicImage) -> DynamicImage {
img.grayscale()
}
/// Convert to black and white (binary)
fn to_black_and_white(img: &DynamicImage, threshold: u8) -> DynamicImage {
let gray = img.to_luma8();
let binary: image::GrayImage = image::GrayImage::from_fn(gray.width(), gray.height(), |x, y| {
let pixel = gray.get_pixel(x, y)[0];
let value = if pixel > threshold { 255 } else { 0 };
image::Luma([value])
});
DynamicImage::ImageLuma8(binary)
}
/// Invert colors
fn invert_colors(img: &DynamicImage) -> DynamicImage {
img.invert()
}
// 6. Alpha Channel Handling
/// Remove alpha channel (convert to RGB)
fn remove_alpha(img: &DynamicImage) -> DynamicImage {
img.to_rgb8().into()
}
/// Add alpha channel (convert to RGBA)
fn add_alpha(img: &DynamicImage) -> DynamicImage {
img.to_rgba8().into()
}
/// Apply transparency mask
fn apply_alpha_mask(img: &DynamicImage, mask: &DynamicImage) -> Result<DynamicImage, image::ImageError> {
let mut rgba = img.to_rgba8();
let mask_gray = mask.to_luma8();
for (x, y, pixel) in rgba.enumerate_pixels_mut() {
if let Some(mask_pixel) = mask_gray.get_pixel_checked(x, y) {
pixel[3] = mask_pixel[0];
}
}
Ok(DynamicImage::ImageRgba8(rgba))
}
// 7. Format Validation
/// Detect format from file
fn detect_format(path: &str) -> Option<ImageFormat> {
ImageFormat::from_path(path).ok()
}
/// Check if format supports transparency
fn supports_transparency(format: ImageFormat) -> bool {
matches!(format, ImageFormat::Png | ImageFormat::WebP | ImageFormat::Ico)
}
/// Check if format is lossy
fn is_lossy_format(format: ImageFormat) -> bool {
matches!(format, ImageFormat::Jpeg | ImageFormat::WebP)
}
// 8. Conversion Utilities
/// Auto-convert based on input format
fn auto_convert(input_path: &str, output_path: &str) -> Result<(), image::ImageError> {
let img = image::open(input_path)?;
img.save(output_path)?;
Ok(())
}
/// Convert with format preservation check
fn convert_safe(input_path: &str, output_path: &str) -> Result<bool, image::ImageError> {
let input_format = detect_format(input_path).unwrap();
let output_format = detect_format(output_path).unwrap();
if input_format == output_format {
return Ok(false); // No conversion needed
}
// Check for loss of transparency
if !supports_transparency(output_format) {
let img = image::open(input_path)?;
if img.color().has_alpha() {
// Remove alpha before saving
let rgb = remove_alpha(&img);
rgb.save(output_path)?;
return Ok(true);
}
}
auto_convert(input_path, output_path)?;
Ok(true)
}
// 9. Special Conversions
/// Convert to grayscale JPEG
fn to_grayscale_jpeg(img: &DynamicImage, output_path: &str, quality: u8) -> Result<(), image::ImageError> {
let gray = to_grayscale(img);
to_jpeg_with_quality(&gray, output_path, quality)?;
Ok(())
}
/// Convert to thumbnail JPEG
fn to_thumbnail_jpeg(img: &DynamicImage, output_path: &str, size: u32, quality: u8) -> Result<(), image::ImageError> {
let thumb = img.thumbnail(size, size);
to_jpeg_with_quality(&thumb, output_path, quality)?;
Ok(())
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust Image Format Conversion Examples ===\n");
// Create test image with RGBA
use image::RgbaImage;
let test_img: DynamicImage = RgbaImage::from_fn(400, 300, |x, y| {
let r = ((x as f32 / 400.0) * 255.0) as u8;
let g = ((y as f32 / 300.0) * 255.0) as u8;
let b = 128;
let a = 255;
image::Rgba([r, g, b, a])
}).into();
// Save test image
test_img.save("test_rgba.png")?;
println!("Created test image");
// 1. Basic conversions
println!("
--- 1. Basic Conversions ---");
convert_format(&test_img, "output.jpg", ImageFormat::Jpeg)?;
convert_format(&test_img, "output.bmp", ImageFormat::Bmp)?;
convert_format(&test_img, "output.ppm", ImageFormat::Pnm)?;
println!("Converted to JPG, BMP, PPM");
// 2. JPEG with quality
println!("
--- 2. JPEG Quality Levels ---");
to_jpeg_with_quality(&test_img, "high.jpg", 90)?;
to_jpeg_with_quality(&test_img, "medium.jpg", 60)?;
to_jpeg_with_quality(&test_img, "low.jpg", 30)?;
println!("Created JPEGs with 90%, 60%, 30% quality");
// 3. PNG compression
println!("
--- 3. PNG Compression ---");
to_png_with_compression(&test_img, "fast.png", image::codecs::png::CompressionType::Fast)?;
to_png_with_compression(&test_img, "best.png", image::codecs::png::CompressionType::Best)?;
println!("Created PNGs with Fast and Best compression");
// 4. Grayscale conversion
println!("
--- 4. Grayscale Conversion ---");
let gray = to_grayscale(&test_img);
gray.save("grayscale.jpg")?;
println!("Created grayscale JPEG");
// 5. Black and white
println!("
--- 5. Black and White ---");
let bw = to_black_and_white(&test_img, 128);
bw.save("blackwhite.png")?;
println!("Created black and white image");
// 6. Invert colors
println!("
--- 6. Invert Colors ---");
let inverted = invert_colors(&test_img);
inverted.save("inverted.png")?;
println!("Created color-inverted image");
// 7. Alpha handling
println!("
--- 7. Alpha Channel ---");
let no_alpha = remove_alpha(&test_img);
no_alpha.save("no_alpha.jpg")?;
println!("Removed alpha for JPEG conversion");
// 8. Format detection
println!("
--- 8. Format Detection ---");
println!("test_rgba.png format: {:?}", detect_format("test_rgba.png"));
println!("output.jpg format: {:?}", detect_format("output.jpg"));
// 9. Format properties
println!("
--- 9. Format Properties ---");
println!("PNG supports transparency: {}", supports_transparency(ImageFormat::Png));
println!("JPEG supports transparency: {}", supports_transparency(ImageFormat::Jpeg));
println!("JPEG is lossy: {}", is_lossy_format(ImageFormat::Jpeg));
println!("PNG is lossy: {}", is_lossy_format(ImageFormat::Png));
// 10. Thumbnail conversion
println!("
--- 10. Thumbnail JPEG ---");
to_thumbnail_jpeg(&test_img, "thumb.jpg", 150, 70)?;
println!("Created 150x150 thumbnail JPEG");
println!("
=== All Image Format Conversion Examples Completed ===");
Ok(())
}