加载中...

Rust 图像处理神器:从加载到编辑,一步到位!

Rust 图像处理神器:从加载到编辑,一步到位!

大家好,我是梦兽。一个 WEB 全栈开发和 Rust 爱好者。如果你对 Rust 非常感兴趣,可以关注梦兽编程公众号获取群,进入和梦兽一起交流。

在这篇文章中,我们将探讨如何使用Rust语言中的image crate来处理图像。

具体来说,我们会查看以下内容:

  • 从现有的图像、字节或Base64字符串创建Rust DynamicImage
  • 获取图像信息,例如尺寸、颜色类型和像素数据
  • 修改图像:灰度化、调整对比度、增亮、裁剪、缩放等
  • 将Rust DynamicImage保存到磁盘
  • 作为附加内容,我还将分享如何使用系统默认应用程序打开创建的图像文件

现在让我们开始吧!

创建Rust图像 从文件路径 为了从路径读取图像,我们将使用ImageReader::open。这会返回一个ImageReader<std::io::BufReader<File>>。通过调用decode()方法,我们可以获得一个DynamicImage,它是所有支持的ImageBuffer<P>类型的枚举。为了方便起见,DynamicImage重新实现了所有的图像处理函数。

ini
代码解读
复制代码
let image_path = "./pikachu.jpg"; let image_from_path = ImageReader::open(image_path)?.decode()?;

当然,像往常一样!皮卡丘!以下是我正在测试的图像!

New Image

从字节读取

我们可以用两种不同的方式来做这件事。一种是使用ImageReader::new,另一种是使用load_from_memory

首先,让我们使用fs::read来获取图像的字节数据。

ini
代码解读
复制代码
let image_bytes = fs::read(image_path)?;

然后我们可以如下所示加载我们的图像。

ruby
代码解读
复制代码
let image_from_bytes_1 = image::ImageReader::new(std::io::Cursor::new(&image_bytes)).with_guessed_format()?.decode()?; let image_from_bytes_2 = image::load_from_memory(&image_bytes)?;

从 Base64 编码的字符串

这是图像生成AI常见的响应类型。以下是一个例子:

bash
代码解读
复制代码
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAYAAACadoJw……

要从中创建一个 DynamicImage,需要三个步骤:

  1. 提取原始内容,即 data:image/png;base64, 之后的部分,
  2. 解码为字节,
  3. 使用上面的方法来创建 DynamicImage
ini
代码解读
复制代码
let base64_string = "data:image/png;base64,iVB......"; let raw_content_string = base64_string.trim_start_matches("data:image/png;base64,"); let decode_bytes = BASE64_STANDARD.decode(base64_string)?; let img = image::load_from_memory(&decode_bytes)?;

获取图像信息

尺寸

arduino
代码解读
复制代码
println!("dimensions: {:?}", image_from_bytes_1.dimensions()); // dimensions: (600, 565)

我们想图像的颜色类型

css
代码解读
复制代码
println!("color: {:?}", image_from_bytes_1.color()); //color: Rgb8 /** L8:8位灰度图像 LA8:8位带Alpha通道的灰度图像 RGB8:24位RGB图像 RGBA8:32位RGBA图像 RGBAF32:32位浮点数RGB图像 RGBAFA32:32位浮点数RGBA图像 */

像素信息

ini
代码解读
复制代码
let pixel_iterator = image_from_bytes_1.pixels();

这将返回一个遍历图像像素的迭代器。迭代器会生成每个像素的坐标及其值。

将图像保存到磁盘

在我们进入图像修改之前,让我们先看看如何将 DynamicImage 对象保存到磁盘,这样我们就可以在下一阶段可视化我们的修改了!

这很简单,只需使用 img.save("./pikachu_new.jpg")?;

修改图像

在这里我只包含几个你可能会觉得有用的主功能。

  • 灰度化
  • 模糊
  • 调整对比度
  • 增亮
  • 裁剪
  • 缩放

但是这个库提供了许多其他有趣的功能,所以你可以尝试使用它来发现更多的功能!

灰度化

ini
代码解读
复制代码
let gray = image_from_path.grayscale(); gray.save("./test/gray.jpg")?;

New Image

Blur

ini
代码解读
复制代码
let blur = image_from_path.blur(10.0); blur.save("./test/blur.jpg")?;

传递给模糊函数的参数是sigma值,用于确定应用于图像的模糊程度。较高的sigma值会导致更多的模糊,而较低的sigma值会导致较少的模糊。

我们原始图像使用sigma值为10.0的模糊效果如下。

New Image

调整对比度

要调整这张图像的对比度,我们将使用 adjust_contrast(c:f32) 方法,其中 c 是调整对比度的程度。负值会降低对比度,而正值会增加对比度。

ini
代码解读
复制代码
let contrast = image_from_path.adjust_contrast(-50.0); contrast.save("./test/contrast.jpg")?;

New Image

增亮

ini
代码解读
复制代码
let brighten = image_from_path.brighten(100); brighten.save("./test/brighten.jpg")?;

传递给函数的整数是用于增亮每个像素的程度。负值会减少亮度,而正值会增加亮度。

裁剪

要使用一个左上角位于点 (x, y) 并且大小为 (width, height) 的矩形来裁剪图像,我们可以使用 crop_imm(x, y, width, height) 函数。

ini
代码解读
复制代码
let crop = image_from_path.crop_imm(0, 0, 300, 300); crop.save("./test/crop.jpg")?;

图片.png

New Image 还有一种裁剪方法:crop(…),但请避免使用它,因为它将被我们上面提到的 crop_imm 所替代。

缩放

最后但同样重要的是,我们还有缩放功能。

ruby
代码解读
复制代码
let resize = image_from_path.resize(300, 300, image::imageops::FilterType::Gaussian); resize.save("./test/resize.jpg")?;

第一个和第二个参数应该很清楚,它们是结果图像的宽度和高度。

第三个参数是在缩放图像时所使用的采样滤镜。除了上面提到的高斯滤镜外,我们还可以选择:

  • Nearest 表示最近邻插值
  • Triangle 表示线性滤镜
  • CatmullRom 表示三次滤镜
  • Lanczos3 表示窗口大小为3的兰佐斯滤镜

图片.png

New Image

附加内容:打开图像

在你创建了一个新的图像之后,你可能想要使用系统的默认程序来打开它。

要做到这一点,我们可以使用 open crate 并简单地调用 open::that(image_path)

如果你想使用一个分离的进程来打开图像,这在程序阻塞或希望其生命周期超过你的应用时非常有用,那么我们可以使用 open::that_detached(image_path)

感谢阅读!

今天的内容就到这里!和我那超级可爱的皮卡丘一起玩耍让我的一天都很愉快!

希望你的一天也和我一样美好!

祝你图像处理愉快!

注意

感谢阅读!感谢您的时间,并希望您觉得这篇文章有价值。在您的下一个 JavaScript 项目中尝试使用柯里化,并在下面的评论中告诉我它如何改善了您的编码体验!

创建和维护这个博客以及相关的库带来了十分庞大的工作量,即便我十分热爱它们,仍然需要你们的支持。或者转发文章。通过赞助我,可以让我有能投入更多时间与精力在创造新内容,开发新功能上。赞助我最好的办法是微信公众号看看广告。