2 个不稳定版本
0.2.0 | 2023年3月16日 |
---|---|
0.1.0 | 2022年11月4日 |
#338 in 图像
110KB
2.5K SLoC
picture
一个快速灵活的图像处理库。
警告:wip
这个库仍然是一个 wip。虽然它的基础已经存在(但并不稳定),但它还缺少许多便利性和生活质量的特性——主要与格式相关。
它还需要测试™(非常少)。
待办事项
- 更好的 & 扩展的图像格式支持(目前非常简陋,仅支持 png 和 qoi)
- 添加更多的测试
- 尝试减少不安全块的使用
分形示例
基于 image
库的分形示例
use picture::{formats::png::PngEncoder, prelude::*};
use std::io::Write;
fn main() {
let (width, height) = (1024, 1024);
let mut img = Rgb8Img::new(width, height);
let scalex = 3.0 / width as f32;
let scaley = 3.0 / height as f32;
for ((x, y), pixel) in img.pixels_with_coords_mut() {
let cx = y as f32 * scalex - 1.5;
let cy = x as f32 * scaley - 1.5;
let c = num_complex::Complex::new(-0.4, 0.6);
let mut z = num_complex::Complex::new(cx, cy);
let mut g = 0;
while g < 255 && z.norm() <= 2.0 {
z = z * z + c;
g += 1;
}
*pixel = RGB8 {
r: ((x * 255) / width) as u8,
g,
b: ((y * 255) / height) as u8,
};
}
let encoded = PngEncoder::default().encode(img).unwrap();
let mut f = std::fs::File::create("frac.png").unwrap();
f.write_all(&encoded[..]).unwrap();
}
(你可以在 这里 找到这段代码)
不连续可变视图示例
picture
最酷的特性之一是能够对视图有不相交的可变视图。以下示例交换了 ImgBuf
的两个水平半部分,然后保存了结果。
use picture::{
formats::png::{PngDecoder, PngEncoder, PngImage},
prelude::*,
};
use std::io::Write;
fn swap<I1, I2, P>(a: &mut I1, b: &mut I2)
where
I1: ImgViewMut<Pixel = P>,
I2: ImgViewMut<Pixel = P>,
{
assert!(a.dimensions() == b.dimensions());
a.pixels_mut()
.zip(b.pixels_mut())
.for_each(|(a, b)| std::mem::swap(a, b));
}
fn main() {
let colorful = PngDecoder
.decode_from_path("examples/images/colorful.png")
.unwrap();
let PngImage::Rgb(mut colorful) = colorful else {
unreachable!()
};
let (mut a, mut b) = colorful.split_x_at_mut(colorful.width() / 2).unwrap();
swap(&mut a, &mut b);
let encoded = PngEncoder::default().encode(colorful).unwrap();
let mut f = std::fs::File::create("swapped.png").unwrap();
f.write_all(&encoded[..]).unwrap();
}
(你可以在 这里 也找到这段代码!)
ImgViewMut
特质有许多方法可以获得不相交的可变视图: split_x_at_mut
、split_y_at_mut
和 view_mut_multiple
。
性能
我编写了一些 基准测试 来比较 picture
和 image
,但我不是写这些测试的专家——所以请对这些结果持保留态度。基准测试是在我的 ryzen 5 1600 上执行的,使用 lto = "thin"
。
基准测试 | 时间 |
---|---|
Diff 256x256/Picture/ | [377.45 µs 379.36 µs 381.44 µs] |
Diff 256x256/Image/ | [735.66 µs 744.57 µs 753.50 µs] |
Fractal 256x256/Picture/ | [8.2667 ms 8.3979 ms 8.5334 ms] |
Fractal 256x256/Image/ | [9.0005 ms 9.1315 ms 9.2613 ms] |
Match 16x16 in 256x256/Picture/ | [183.25 ms 184.11 ms 185.00 ms] |
Match 16x16 in 256x256/Image/ | [188.99 毫秒 190.29 毫秒 191.65 毫秒] |
Lancoz 降采样/图片/ | [54.864 毫秒 55.451 毫秒 56.069 毫秒] |
Lancoz 降采样/图像/ | [55.418 毫秒 56.024 毫秒 56.655 毫秒] |
Lancoz 上采样/图片/ | [396.48 毫秒 401.48 毫秒 406.81 毫秒] |
Lancoz 上采样/图像/ | [861.12 毫秒 863.81 毫秒 866.49 毫秒] |
您可以尝试自己运行这些命令,使用简单的 cargo bench
。
不安全
这个crate在许多地方使用了unsafe
,但我已经尽力让所有代码听起来都很安全——包括在每个unsafe
块上方添加SAFETY:
注释。然而,这是我第一个包含大量unsafe
的大项目,所以如果您发现任何安全性漏洞,请告诉我!
依赖关系
~1.6–2.3MB
~46K SLoC