Trabalho com imagens em Rust: redimensionar e cortar com a biblioteca image
\n\nRust é uma linguagem de programação de sistemas moderna que está ganhando popularidade em tarefas que exigem alto desempenho e segurança. Uma dessas tarefas é o processamento de imagens. Neste artigo, veremos detalhadamente como redimensionar (resize) e cortar (crop) imagens em Rust usando a poderosa e conveniente biblioteca image. Você aprenderá como instalar a biblioteca, carregar uma imagem, aplicar transformações e salvar o resultado.
Instalação e inclusão da biblioteca image
\n\nA biblioteca image é o padrão de facto para trabalhar com imagens raster no ecossistema Rust. Ela suporta vários formatos (PNG, JPEG, GIF, BMP, WEBP e outros) e fornece um amplo conjunto de funções para processamento.
Para começar, adicione a dependência no arquivo Cargo.toml:
[dependencies]\nimage = "0.25"\n\nDepois disso, você pode importar os módulos necessários no código:
\n\nuse std::path::Path;\nuse image::{open, DynamicImage, GenericImageView, imageops::FilterType};\n\nCarregamento e salvamento de imagens
\n\nO primeiro passo é carregar uma imagem de um arquivo. A biblioteca detecta automaticamente o formato pela extensão. Vejamos um exemplo básico:
\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n // Carregamos a imagem\n let img = open("input.jpg")?;\n println!("Tamanho: {:?}", img.dimensions());\n // Salvamos em outro formato\n img.save("output.png")?;\n Ok(())\n}\n\nO método open() retorna um DynamicImage — uma enumeração que pode armazenar a imagem em um de vários formatos internos (RGB8, RGBA8, Gray8, etc.). O método dimensions() retorna uma tupla (u32, u32) — largura e altura.
Redimensionamento (resize)
\n\nA função resize() recebe uma nova largura, altura e o tipo de filtro. O filtro afeta a qualidade do resultado e a velocidade de execução. Aqui estão os principais filtros:
- \n
- Nearest — rápido, mas com baixa qualidade (pixelização). \n
- Lanczos3 — alta qualidade, porém mais lento. \n
- CatmullRom — bom equilíbrio entre velocidade e qualidade. \n
- Gaussian — desfoca a imagem ao reduzir. \n
Exemplo de redimensionamento para 800x600 pixels:
\n\nuse 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!("Novo tamanho: {:?}", resized.dimensions());\n Ok(())\n}\n\nSe precisar manter as proporções, use resize_to_fill() (preenche a área, cortando o excesso) ou resize_to_fit() (encaixa nas dimensões especificadas, adicionando espaços vazios). Exemplo:
// Encaixar em um retângulo 400x400, mantendo as proporções\nlet fitted = img.resize_to_fit(400, 400, FilterType::CatmullRom);\nfitted.save("fitted.jpg")?;\n\n// Preencher o retângulo 400x400, cortando as bordas\nlet filled = img.resize_to_fill(400, 400, FilterType::Lanczos3);\nfilled.save("filled.jpg")?;\n\nCorte de imagem (crop)
\n\nO corte é realizado com o método crop(), que recebe as coordenadas do canto superior esquerdo (x, y), bem como a largura e a altura da área. Importante: as coordenadas e dimensões não devem ultrapassar os limites da imagem original, caso contrário ocorrerá um pânico.
Exemplo de corte da parte central com tamanho 300x200:
\n\nfn crop_example() -> Result<(), Box<dyn std::error::Error>> {\n let img = open("input.jpg")?;\n let (width, height) = img.dimensions()