我正在使用图像机箱进行图片处理,并希望创建一个小包装器,以使我的代码更加美观。
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类型,我在源代码中找不到任何有用的东西。我试着重读“锈书”、“示例”、“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 {
}但对我的箱子来说不是公开的。
发布于 2016-02-18 20:37:34
查看ImageBuffer,我们可以看到类型参数的特性要求:
impl<P, Container> ImageBuffer<P, Container>
where P: Pixel + 'static,
P::Subpixel: 'static,
Container: Deref<Target=[P::Subpixel]>因此,重要的是,第二种类型的参数可以取消对子像素片的引用。Subpixel是由特性决定的,它有几个实现:
Rgb<T>Luma<T>Rgba<T>LumaA<T>其中T是亚像素类型。
这一切都是相当复杂的,但应该提供一个良好的权力和一般性。
请注意,我只显示了其中一个实现块。还有一些需要DerefMut或要求亚像素为u8。
你到底是怎么用的?首先,您需要选择特定的颜色和亚像素类型。根据您的颜色,它看起来您想使用4通道,8位的颜色类型.那将是Rgba。
有许多类型可以取消对&[u8]或&mut [u8]的引用。显而易见的(但不仅仅是!)选择将是一个Vec<u8>。
将这两者结合起来,您的结构需要如下所示:
buffer: image::ImageBuffer<Rgba<u8>, Vec<u8>>,然后,这只是一个创建结构和做事情的问题:
extern crate image;
use image::{ImageBuffer, Pixel, Rgba};
pub struct Picture {
buffer: ImageBuffer<Rgba<u8>, Vec<u8>>,
}
impl Picture {
fn new(width: u32, height: u32) -> Self {
// There's probably a cleaner way to figure out the right size
let storage = vec![0; 4 * width as usize * height as usize];
let buf = ImageBuffer::from_raw(width, height, storage).unwrap();
Picture {
buffer: buf,
}
}
fn fill_red(&mut self) {
let color = Rgba::from_channels(255, 0, 0, 255);
for p in self.buffer.pixels_mut() {
*p = color;
}
}
}
fn main() {
let mut pic = Picture::new(256, 256);
pic.fill_red();
}请注意,ImageBuffer已经跟踪了宽度和高度,因此没有真正的理由再次跟踪它们。
然而,所有这一切都是困难的。有一些像new这样的方便函数将为您分配存储:
buffer: ImageBuffer::new(width, height),这些函数是硬编码的,以返回一个Vec作为Container。如果您没有在文档中看到这一点,您可以尝试类似于打印类型的方法
let () = ImageBuffer::new(width, height);这将告诉您错误消息中的类型:
expected `image::buffer::ImageBuffer<_, collections::vec::Vec<_>>`,https://stackoverflow.com/questions/35488820
复制相似问题