在 Rust 中处理图像:库概览与实践示例
Rust 是一种现代系统编程语言,在对高性能和可靠性要求较高的领域越来越受欢迎。图像处理也不例外:Rust 生态系统提供了多个成熟的库,用于图像的加载、处理、转换和分析。在本文中,我们将介绍主要工具:image、fast_image_resize 和 photon-rs,并提供常见任务的代码示例。
核心库:image
image crate(0.25.x 版本)是 Rust 中图像处理的事实标准。它支持读写多种格式:PNG、JPEG、BMP、GIF、TIFF、WebP 等。该库提供了方便的数据结构来表示图像(DynamicImage、RgbImage、GrayImage)以及丰富的操作集:调整大小、裁剪、旋转、滤镜、色彩空间转换。
加载、调整大小并保存图像的示例:
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("无法打开图像"); let resized = img.resize_exact(new_width, new_height, FilterType::Lanczos3); resized.save(output_path).expect("无法保存图像"); println!("图像已调整大小并保存至 {}", output_path);}
fn main() { resize_image("input.jpg", "output.png", 800, 600);}image 库还支持直接操作像素。例如,可以访问每个像素并更改其颜色:
use image::{GenericImage, Rgba};
fn invert_colors(path: &str) { let mut img = image::open(path).expect("打开错误"); 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();}高性能调整大小:fast_image_resize
如果您的任务是多次调整图像大小并追求最高速度,请关注 fast_image_resize crate。它使用 SIMD 指令(SSE、AVX2、NEON)和优化算法(Lanczos、Catmull-Rom、Mitchell)。该库直接操作原始像素数组,从而最大限度地减少开销。
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) { // 通过 image 加载图像 let img = image::open(input_path).expect("打开错误"); let (width, height) = img.dimensions(); let rgba = img.to_rgba8();
// 为 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();
// 配置调整大小器 let mut resizer = fr::Resizer::new(fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)); resizer.resize(&src_view, &mut dst_view).expect("调整大小错误");
// 通过 image 保存结果 let result_img = image::RgbaImage::from_raw(new_width, new_height, dst_image.into_vec()).unwrap(); result_img.save(output_path).unwrap();}根据测试,fast_image_resize 比标准调整大小快 2-5 倍