James Hermes
James Hermes

Reputation: 17

Unable to have an ImageBuffer in a struct — two arguments needed and only provided one

I am new to Rust and still learning. I am a bit confused as to why when I compile this code it fails. I am building it with Cargo on my Linux development machine

extern crate image;
extern crate rand;

use image::{ImageBuffer, Rgb};
use rand::Rng;


struct ImageCanvas {
    image: image::ImageBuffer,
    WIDTH: i32,
    HEIGHT: i32,
    xPosition: i32,
    yPosition: i32
}

impl ImageCanvas {

    pub fn new(width: i32, height: i32) -> ImageCanvas {

        // create a new instance of an ImagePen.
        ImageCanvas{
            image: ImageBuffer::<Rgb<u8>>::new(width, height),
            WIDTH: width, 
            HEIGHT: height, 
            xPosition: 0, 
            yPosition: 0
        }

    }

    pub fn paint(&self, x: i32, y: i32, rgb: i32){

        self.xPosition = x;
        self.yPosition = y;

        //RGB should be an array.
        self.image.get_pixel_mut(self.xPosition, self.yPosition).data = rgb;

    }

}

fn main() {

    let canvas = ImageCanvas::new(50, 50);

    canvas.paint(1, 1, [rand::thread_rng().gen_range(1, 255), 
                        rand::thread_rng().gen_range(1, 255), 
                        rand::thread_rng().gen_range(1, 255)]);

    canvas.image.save("yay.png").unwrap();

}

The error:

src/main.rs:9:9: 9:27 error: wrong number of type arguments: expected 2,                  found 0 [E0243]
src/main.rs:9   image: image::ImageBuffer,
                   ^~~~~~~~~~~~~~~~~~
src/main.rs:9:9: 9:27 help: run `rustc --explain E0243` to see a detailed   explanation
error: aborting due to previous error

I am not sure why it is giving me this error. I have searched, but I haven't seen any other post about a noob like me not understanding the OOD of Rust.

Upvotes: 0

Views: 265

Answers (2)

Sean Perry
Sean Perry

Reputation: 3886

You are actually using an RGB Image so why not used the specialized version

extern crate image;
extern crate rand;

use image::{RgbImage, Rgb};
use rand::Rng;


// Had to change all of the `i32` to `u32`. I agree, `i32` makes more sense.
struct ImageCanvas {
    image: image::RgbImage, // image::ImageBuffer<Rgb<u8>>,
    WIDTH: u32,
    HEIGHT: u32,
    xPosition: u32,
    yPosition: u32
}

impl ImageCanvas {

    pub fn new(width: u32, height: u32) -> ImageCanvas {

        // create a new instance of an ImagePen.
        ImageCanvas{
            image: RgbImage::new(width, height), //ImageBuffer::<Rgb<u8>>::new(width, height),
            WIDTH: width, 
            HEIGHT: height, 
            xPosition: 0, 
            yPosition: 0
        }

    }

    // RGB _IS_ an array
    // note the need for `mut`
    pub fn paint(&mut self, x: u32, y: u32, rgb: [u8;3]){

        self.xPosition = x;
        self.yPosition = y;

        self.image.get_pixel_mut(self.xPosition, self.yPosition).data = rgb;

    }

}

fn main() {

    // `mut` here too
    let mut canvas = ImageCanvas::new(50, 50);

    canvas.paint(1, 1, [rand::thread_rng().gen_range(1, 255), 
                        rand::thread_rng().gen_range(1, 255), 
                        rand::thread_rng().gen_range(1, 255)]);

    canvas.image.save("yay.png").unwrap();

}

Upvotes: 1

Jarod42
Jarod42

Reputation: 217135

image::ImageBuffer is a parametrized struct:

pub struct ImageBuffer<P: Pixel, Container> {
    // some fields omitted
}

So you have to provide these parameters in your struct ImageCanvas.

something like

struct ImageCanvas<P: Pixel, Container> {
    image: image::ImageBuffer<P, Container>,
    WIDTH: i32,
    HEIGHT: i32,
    xPosition: i32,
    yPosition: i32
}

or

struct ImageCanvas {
    image: image::ImageBuffer<RGB<u8>, Vec<RGB<u8>>>,
    WIDTH: i32,
    HEIGHT: i32,
    xPosition: i32,
    yPosition: i32
}

Upvotes: 3

Related Questions