Working with Images in Rust: From Loading to Filtering
Rust is a modern systems language that is gaining popularity not only in web development and systems programming but also in the field of multimedia processing. Thanks to its performance and safety, Rust is well-suited for tasks involving images. In this article, we will look at the key libraries and tools that allow you to work efficiently with raster graphics.
The Main Library: image
The image library is the de facto standard for working with images in the Rust ecosystem. It supports dozens of formats (PNG, JPEG, GIF, BMP, WebP, TIFF, and others) and provides a convenient API for loading, processing, and saving images.
Installation — add to Cargo.toml:
[dependencies]image = "0.25"Loading and Saving Images
Let's look at basic operations: open a file, resize it, and save it in a different format.
use image::{DynamicImage, GenericImageView};use std::path::Path;
fn main() { // Load the image let img = image::open("input.jpg").expect("Failed to open file");
// Print information println!("Size: {}x{}", img.width(), img.height()); println!("Color mode: {:?}", img.color());
// Resize to 200x200 (preserving aspect ratio) let resized = img.resize(200, 200, image::imageops::FilterType::Lanczos3);
// Save as PNG resized.save("output.png").expect("Error saving");}Basic Processing Operations
The image library provides the imageops module with a set of ready-made filters and transformations.
- Rotation and Flipping:
use image::DynamicImage;
fn rotate_and_flip(img: &DynamicImage) { // Rotate 90 degrees clockwise let rotated = img.rotate90(); // Flip horizontally let flipped = img.fliph(); // Flip vertically let flipped_v = img.flipv();}- Crop:
fn crop_example(img: &DynamicImage) { // Crop a rectangle: x=50, y=30, width=200, height=150 let cropped = img.crop_imm(50, 30, 200, 150); cropped.save("cropped.png").unwrap();}- Adjusting Brightness and Contrast:
fn adjust_brightness(img: &DynamicImage) { // Increase brightness by 50 (value can be negative) let brighter = image::imageops::brighten(img, 50); // Increase contrast let contrasted = image::imageops::contrast(img, 1.5);}Filters and Effects
The library includes several built-in filters. Here are examples of the most useful ones:
use image::imageops::FilterType;
fn apply_filters(img: &DynamicImage) { // Gaussian blur (sigma = 2.0) let blurred = image::imageops::blur(img, 2.0);
// Sharpen let sharpened = image::imageops::unsharpen(img, 5.0, 2);
// Convert to grayscale let gray = img.grayscale();
// Apply threshold filter (binarization) let threshold = image::imageops::threshold(img, 128);
// Save all results blurred.save("blurred.png").unwrap(); sharpened.save("sharpened.png").unwrap(); gray.save("gray.png").unwrap();}Working with Pixels Directly
If you need full control over every pixel, the library allows access to raw data:
use image::Rgba;
fn pixel_manipulation(mut img: image::RgbaImage) { for pixel in img.pixels_mut() { // Invert colors pixel[0] = 255 - pixel[0]; // Red pixel[1] = 255 - pixel[1];