Trabalho com imagens em Rust: do carregamento à filtragem
Rust é uma linguagem de sistema moderna que está ganhando popularidade não apenas no desenvolvimento web e programação de sistemas, mas também na área de processamento multimídia. Graças ao seu desempenho e segurança, Rust é excelente para tarefas relacionadas a imagens. Neste artigo, vamos explorar as principais bibliotecas e ferramentas que permitem trabalhar eficientemente com gráficos raster.
Biblioteca principal: image
A biblioteca image é o padrão de facto para trabalhar com imagens no ecossistema Rust. Ela suporta dezenas de formatos (PNG, JPEG, GIF, BMP, WebP, TIFF e outros) e fornece uma API conveniente para carregar, processar e salvar imagens.
Instalação — adicione ao Cargo.toml:
[dependencies]image = "0.25"Carregamento e salvamento de imagens
Vamos considerar as operações básicas: abrir um arquivo, redimensionar e salvar em outro formato.
use image::{DynamicImage, GenericImageView};use std::path::Path;
fn main() { // Carregamos a imagem let img = image::open("input.jpg").expect("Não foi possível abrir o arquivo");
// Exibimos informações println!("Tamanho: {}x{}", img.width(), img.height()); println!("Modo de cor: {:?}", img.color());
// Redimensionamos para 200x200 (mantendo a proporção) let resized = img.resize(200, 200, image::imageops::FilterType::Lanczos3);
// Salvamos em PNG resized.save("output.png").expect("Erro ao salvar");}Operações principais de processamento
A biblioteca image fornece o módulo imageops com um conjunto de filtros e transformações prontas.
- Rotação e espelhamento:
use image::DynamicImage;
fn rotate_and_flip(img: &DynamicImage) { // Rotação de 90 graus no sentido horário let rotated = img.rotate90(); // Espelhamento horizontal let flipped = img.fliph(); // Espelhamento vertical let flipped_v = img.flipv();}- Corte (crop):
fn crop_example(img: &DynamicImage) { // Cortamos um retângulo: x=50, y=30, largura=200, altura=150 let cropped = img.crop_imm(50, 30, 200, 150); cropped.save("cropped.png").unwrap();}- Ajuste de brilho e contraste:
fn adjust_brightness(img: &DynamicImage) { // Aumentamos o brilho em 50 (o valor pode ser negativo) let brighter = image::imageops::brighten(img, 50); // Aumentamos o contraste let contrasted = image::imageops::contrast(img, 1.5);}Filtros e efeitos
A biblioteca inclui vários filtros embutidos. Aqui estão exemplos dos mais úteis:
use image::imageops::FilterType;
fn apply_filters(img: &DynamicImage) { // Desfoque Gaussiano (sigma = 2.0) let blurred = image::imageops::blur(img, 2.0);
// Aumento de nitidez let sharpened = image::imageops::unsharpen(img, 5.0, 2);
// Conversão para tons de cinza let gray = img.grayscale();
// Aplicação de filtro de limiar (binarização) let threshold = image::imageops::threshold(img, 128);
// Salvamos todos os resultados blurred.save("blurred.png").unwrap(); sharpened.save("sharpened.png").unwrap(); gray.save("gray.png").unwrap();}Trabalhando diretamente com pixels
Se você precisa de controle total sobre cada pixel, a biblioteca permite acesso aos dados brutos:
use image::Rgba;
fn pixel_manipulation(mut img: image::RgbaImage) { for pixel in img.pixels_mut() { // Invertemos as cores pixel[0] = 255 - pixel[0]; // Red pixel[1] = 255 - pixel[1];