Trabajo con imágenes en Rust: resize y crop con la biblioteca image

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: resize y crop con la biblioteca image

\n\n

Rust es un lenguaje de programación de sistemas moderno que está ganando popularidad en tareas que requieren alto rendimiento y seguridad. Una de estas tareas es el procesamiento de imágenes. En este artículo, veremos en detalle cómo cambiar el tamaño (resize) y recortar (crop) imágenes en Rust utilizando la potente y conveniente biblioteca image. Aprenderá cómo instalar la biblioteca, cargar una imagen, aplicar transformaciones y guardar el resultado.

\n\n

Instalación y vinculación de la biblioteca image

\n\n

La biblioteca image es el estándar de facto para trabajar con imágenes rasterizadas en el ecosistema de Rust. Soporta múltiples formatos (PNG, JPEG, GIF, BMP, WEBP y otros) y proporciona un amplio conjunto de funciones para el procesamiento.

\n\n

Para comenzar, agregue la dependencia en el archivo Cargo.toml:

\n\n
[dependencies]\nimage = "0.25"
\n\n

Después de esto, puede importar los módulos necesarios en el código:

\n\n
use std::path::Path;\nuse image::{open, DynamicImage, GenericImageView, imageops::FilterType};
\n\n

Carga y guardado de imágenes

\n\n

El primer paso es cargar una imagen desde un archivo. La biblioteca detectará automáticamente el formato por la extensión. Veamos un ejemplo básico:

\n\n
fn main() -> Result<(), Box<dyn std::error::Error>> {\n    // Cargamos la imagen\n    let img = open("input.jpg")?;\n    println!("Tamaño: {:?}", img.dimensions());\n    // Guardamos en otro formato\n    img.save("output.png")?;\n    Ok(())\n}
\n\n

El método open() devuelve un DynamicImage — una enumeración que puede almacenar la imagen en uno de varios formatos internos (RGB8, RGBA8, Gray8, etc.). El método dimensions() devuelve una tupla (u32, u32) — el ancho y el alto.

\n\n

Cambio de tamaño (resize)

\n\n

La función resize() recibe un nuevo ancho, alto y el tipo de filtro. El filtro afecta la calidad del resultado y la velocidad de ejecución. Estos son los filtros principales:

\n\n
    \n
  • Nearest — rápido, pero de baja calidad (pixelación).
  • \n
  • Lanczos3 — alta calidad, pero más lento.
  • \n
  • CatmullRom — buen equilibrio entre velocidad y calidad.
  • \n
  • Gaussian — desenfoca la imagen al reducirla.
  • \n
\n\n

Ejemplo de cambio de tamaño a 800x600 píxeles:

\n\n
use image::imageops::FilterType;\n\nfn resize_example() -> Result<(), Box<dyn std::error::Error>> {\n    let img = open("input.jpg")?;\n    let resized = img.resize(800, 600, FilterType::Lanczos3);\n    resized.save("resized.jpg")?;\n    println!("Nuevo tamaño: {:?}", resized.dimensions());\n    Ok(())\n}
\n\n

Si necesita mantener las proporciones, use resize_to_fill() (rellena el área, recortando el sobrante) o resize_to_fit() (ajusta dentro de las dimensiones dadas, añadiendo espacios vacíos). Ejemplo:

\n\n
// Ajustar dentro de un rectángulo de 400x400, manteniendo las proporciones\nlet fitted = img.resize_to_fit(400, 400, FilterType::CatmullRom);\nfitted.save("fitted.jpg")?;\n\n// Rellenar el rectángulo de 400x400, recortando los bordes\nlet filled = img.resize_to_fill(400, 400, FilterType::Lanczos3);\nfilled.save("filled.jpg")?;
\n\n

Recorte de imagen (crop)

\n\n

El recorte se realiza con el método crop(), que recibe las coordenadas de la esquina superior izquierda (x, y), así como el ancho y alto del área. Importante: las coordenadas y dimensiones no deben exceder los límites de la imagen original, de lo contrario se producirá un pánico.

\n\n

Ejemplo de recorte de la parte central de tamaño 300x200:

\n\n
fn crop_example() -> Result<(), Box<dyn std::error::Error>> {\n    let img = open("input.jpg")?;\n    let (width, height) = img.dimensions()                    

Recommendations