Trabajo con imágenes en Rust: revisión de las bibliotecas image, fast_image_resize y otras

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo con imágenes en Rust: revisión de bibliotecas y ejemplos prácticos



Rust es un lenguaje de programación de sistemas moderno que está ganando popularidad en áreas que requieren alto rendimiento y confiabilidad. El procesamiento de imágenes no es una excepción: el ecosistema de Rust ofrece varias bibliotecas maduras para cargar, procesar, convertir y analizar imágenes. En este artículo revisaremos las herramientas principales: image, fast_image_resize y photon-rs, además de proporcionar ejemplos de código para tareas típicas.



Biblioteca principal: image



El crate image (versión 0.25.x) es el estándar de facto para trabajar con imágenes en Rust. Soporta lectura y escritura de múltiples formatos: PNG, JPEG, BMP, GIF, TIFF, WebP y otros. La biblioteca proporciona estructuras de datos convenientes para representar imágenes (DynamicImage, RgbImage, GrayImage) y un amplio conjunto de operaciones: cambio de tamaño, recorte, rotación, filtros, conversión de espacios de color.



Ejemplo de carga y guardado de imagen con cambio de tamaño:



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("No se pudo abrir la imagen"); let resized = img.resize_exact(new_width, new_height, FilterType::Lanczos3); resized.save(output_path).expect("No se pudo guardar la imagen"); println!("Imagen redimensionada y guardada en {}", output_path);}

fn main() { resize_image("input.jpg", "output.png", 800, 600);}


La biblioteca image también soporta trabajar directamente con píxeles. Por ejemplo, se puede acceder a cada píxel y cambiar su color:



use image::{GenericImage, Rgba};

fn invert_colors(path: &str) { let mut img = image::open(path).expect("Error al abrir"); 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();}


Cambio de tamaño de alto rendimiento: fast_image_resize



Si tu tarea es redimensionar imágenes repetidamente con la máxima velocidad, presta atención al crate fast_image_resize. Utiliza instrucciones SIMD (SSE, AVX2, NEON) y algoritmos optimizados (Lanczos, Catmull-Rom, Mitchell). La biblioteca trabaja directamente con arreglos de píxeles en bruto, minimizando la sobrecarga.



Ejemplo de uso 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) { // Cargamos la imagen a través de image let img = image::open(input_path).expect("Error al abrir"); let (width, height) = img.dimensions(); let rgba = img.to_rgba8();

// Creamos la vista para 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();

// Configuración del redimensionador let mut resizer = fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)); resizer.resize(&src_view, &mut dst_view).expect("Error al redimensionar");

// Guardamos el resultado a través de image let result_img = image::RgbaImage::from_raw(new_width, new_height, dst_image.into_vec()).unwrap(); result_img.save(output_path).unwrap();}


Según pruebas, fast_image_resize puede ser de 2 a 5 veces más rápido que el redimensionado estándar

Recommendations