Travail avec les images en Rust : aperçu des bibliothèques et exemples pratiques
Rust est un langage de programmation système moderne qui gagne en popularité dans les domaines nécessitant des performances élevées et une grande fiabilité. Le traitement d'images ne fait pas exception : l'écosystème Rust propose plusieurs bibliothèques matures pour le chargement, le traitement, la conversion et l'analyse d'images. Dans cet article, nous examinerons les principaux outils : image, fast_image_resize et photon-rs, et fournirons des exemples de code pour des tâches typiques.
Bibliothèque principale : image
La crate image (version 0.25.x) est la norme de facto pour le travail avec les images en Rust. Elle prend en charge la lecture et l'écriture de nombreux formats : PNG, JPEG, BMP, GIF, TIFF, WebP et autres. La bibliothèque fournit des structures de données pratiques pour représenter les images (DynamicImage, RgbImage, GrayImage) et un large éventail d'opérations : redimensionnement, recadrage, rotation, filtres, conversion d'espaces colorimétriques.
Exemple de chargement et d'enregistrement d'une image avec redimensionnement :
use image::{DynamicImage, GenericImageView, imageops::FilterType};
fn resize_image(input_path: &str, output_path: &str, new_width: u32, new_height: u32) { let img = image::open(input_path).expect("Impossible d'ouvrir l'image"); let resized = img.resize_exact(new_width, new_height, FilterType::Lanczos3); resized.save(output_path).expect("Impossible d'enregistrer l'image"); println!("Image redimensionnée et enregistrée dans {}", output_path);}
fn main() { resize_image("input.jpg", "output.png", 800, 600);}La bibliothèque image prend également en charge le travail direct avec les pixels. Par exemple, on peut accéder à chaque pixel et modifier sa couleur :
use image::{GenericImage, Rgba};
fn invert_colors(path: &str) { let mut img = image::open(path).expect("Erreur d'ouverture"); for (x, y, pixel) in img.enumerate_pixels_mut() { let inverted = Rgba([ 255 - pixel[0], 255 - pixel[1], 255 - pixel[2], pixel[3], ]); img.put_pixel(x, y, inverted); } img.save("inverted.png").unwrap();}Redimensionnement haute performance : fast_image_resize
Si votre tâche consiste à redimensionner des images de manière répétée avec une vitesse maximale, tournez-vous vers la crate fast_image_resize. Elle utilise des instructions SIMD (SSE, AVX2, NEON) et des algorithmes optimisés (Lanczos, Catmull-Rom, Mitchell). La bibliothèque travaille directement avec des tableaux bruts de pixels, ce qui minimise les frais généraux.
Exemple d'utilisation de fast_image_resize :
use fast_image_resize as fr;use image::GenericImageView;
fn resize_fast(input_path: &str, output_path: &str, new_width: u32, new_height: u32) { // Chargement de l'image via image let img = image::open(input_path).expect("Erreur d'ouverture"); let (width, height) = img.dimensions(); let rgba = img.to_rgba8();
// Création d'une vue pour fast_image_resize let src_view = fr::ImageView::new(&rgba, width, height, fr::PixelType::U8x4); let mut dst_image = fr::Image::new(new_width, new_height, fr::PixelType::U8x4); let mut dst_view = dst_image.view_mut();
// Configuration du redimensionneur let mut resizer = fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)); resizer.resize(&src_view, &mut dst_view).expect("Erreur de redimensionnement");
// Sauvegarde du résultat via image let result_img = image::RgbaImage::from_raw(new_width, new_height, dst_image.into_vec()).unwrap(); result_img.save(output_path).unwrap();}D'après les tests, fast_image_resize peut être 2 à 5 fois plus rapide que le redimensionnement standard