从图片灰度学习 Rust 知识点

203 阅读1分钟
use image::{ImageBuffer,DynamicImage,GenericImageView,Rgba};

#[flutter_rust_bridge::frb(sync)]
pub fn luma_image(src: &str, dist: &str) {
    let img = image::open(src).expect("Failed to open image");
    let (width, height) = img.dimensions();
    let mut gray_image = ImageBuffer::new(width, height);

    for (x, y, pixel) in img.pixels() {
        let Rgba([r, g, b, _]) = pixel;
        let luma = (0.299 * r as f32 + 0.587 * g as f32 + 0.114 * b as f32) as u8;
        gray_image.put_pixel(x, y, image::Luma([luma]));
    }
    gray_image.save(dist).expect("Failed to save image");
}

步骤 1 引入图片操作库

对于图片的读取操作都是依靠 引入的image = "0.25.2"库。

步骤 2 读取图片

 let img = image::open(src).expect("Failed to open image");

expect 方法在读取文件发生错误的时候 终止程序,并打印出我们写入的错误日志。读取成功返回我们想要的内容。

类似的还有unwrap(),不一样的是unwrap()的错误信息是系统默认的.

步骤3 获取图片尺寸

let (width, height) = img.dimensions();

步骤4 创建新的图片像素Buffer

let mut gray_image = ImageBuffer::new(width, height);

关键字 mut 可变变量

因为后面会涉及到往 gray_image 中存储数据,也就是修改gray_image 所以需要定义为可变 mut

步骤5 遍历图片像素

for (x, y, pixel) in img.pixels() {}

img.pixels() 返回的是 Pixels 对象。

image.png Pixels 对象为什么能被遍历呢?因为Pixels 实现了 Iterator

![image.png](p0-xtjj-private.juejin.cn/tos-cn-i-73…, y, pixel) 这种写法又是什么意思?%2BhwDL2LPhY6Zg8mQBIHEUBo%3D)

(x, y, pixel) 这种写法又是什么意思?这个是Rust中的元组。如果函数需要返回多个值,又不想创建对象,就可以使用元组。

步骤6 修改每一个像素颜色信息

 let luma = (0.299 * r as f32 + 0.587 * g as f32 + 0.114 * b as f32) as u8;

步骤7 存储到Buffer中

gray_image.put_pixel(x, y, image::Luma([luma]));

步骤8 保存到图片文件

 gray_image.save(dist).expect("Failed to save image");