我正在使用image crate来进行图片处理,并希望创建一个小包装器以使我的代码更有趣 .
extern crate image;
const BLACK: [u8; 4] = [0, 0, 0, 255];
const WHITE: [u8; 4] = [255, 255, 255, 255];
const RED: [u8; 4] = [255, 0, 0, 255];
pub struct Picture {
buffer: image::ImageBuffer,
width: u32,
height: u32
}
impl Picture {
// My functions like fill(), line() etc.
}
但是当我编译它时,我有一个错误:
src\pic.rs:11:13: 11:31 error: wrong number of type arguments: expected 2, found 0 [E0243]
src\pic.rs:11 buffer: image::ImageBuffer,
^~~~~~~~~~~~~~~~~~
在源代码中,我看到 ImageBuffer
接受两个参数:
pub struct ImageBuffer<P: Pixel, Container> {
width: u32,
height: u32,
_phantom: PhantomData<P>,
data: Container,
}
所以我决定将这些参数放在 Picture
声明中:
pub struct Picture {
buffer: image::ImageBuffer<image::Pixel>,
}
并得到另一个错误:
src\pic.rs:11:32: 11:44 error: the value of the associated type `Subpixel` (from the trait `pic::image::buffer::Pixel`) must be specified [E0191]
src\pic.rs:11 buffer: image::ImageBuffer<image::Pixel>,
^~~~~~~~~~~~
这意味着我必须为 Subpixel
类型指定一些值,并且我不知道如何声明 Container
类型,我在源代码中找不到任何有用的东西 . 我试图重新阅读Rust Book,例子, rustc --explain E0191
但我仍然迷失了 .
更新:
在消息来源发现下一个声明
impl<P, Container> ImageBuffer<P, Container>
where P: Pixel + 'static,
P::Subpixel: 'static,
Container: Deref<Target=[P::Subpixel]>
Subpixel
是:
/// Primitive trait from old stdlib
pub trait Primitive: Copy + NumCast + Num + PartialOrd<Self> + Clone + Bounded {
}
但它不公开我的箱子 .
1 回答
查看documentation for ImageBuffer,我们可以看到类型参数的特征要求:
因此,第二类参数可以取消引用一个子像素是很重要的 .
Subpixel
由Pixel trait确定,它有一些实现:Rgb<T>
Luma<T>
Rgba<T>
LumaA<T>
其中
T
是子像素类型 .这一切都非常复杂,但应该提供一点点的力量和普遍性 .
请注意,我只展示了其中一个实现块 . 还有其他需要
DerefMut
或要求子像素为u8
.你是如何实际使用它的?首先,您需要选择特定的颜色和子像素类型 . 根据您的颜色,您似乎想要使用4通道,8位颜色类型 . 那将是Rgba<u8> .
有许多类型可以取消引用
&[u8]
或&mut [u8]
. 明显的(但不仅仅是!)选择是Vec<u8>
.结合这两者,您的结构需要类似于:
然后,这只是创建结构和做事的问题:
请注意
ImageBuffer
已经跟踪了宽度和高度,因此没有理由再次跟踪它们 .然而,所有这些都是艰难的方式 . 有一些便利功能,如
new
,它将为您分配存储:这些函数是硬编码的,以返回
Vec
作为Container
. 如果您在文档中没有看到,可以尝试类似printing the type的内容:哪个会告诉你错误信息中的类型: