15

I'd like to learn Rust and thought it would be fun to procedurally generate images. I've no idea where to start though... piston/rust-image? But even with that where should I begin?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Rik
  • 493
  • 1
  • 3
  • 12
  • BTW, questions will get better answers (and hence be more helpful to you) if they're specific, e.g. including [what you have tried](http://mattgemmell.com/what-have-you-tried/), and points where you're confused/lost, e.g. maybe you don't know how to install the library, maybe you're not sure how to create an image to modify. I've assumed the latter in my answer, but I'm unsure! Be sure to clarify the question if you're still lost. – huon Apr 24 '15 at 01:46
  • Welcome to Stack Overflow! In addition to the existing advice, you should read [What topics can I ask about](http://stackoverflow.com/help/on-topic) and [How to ask a good question](http://stackoverflow.com/help/how-to-ask). For example, it's unclear if you have any experience in procedural image generation in any language. Unfortunately, SO still isn't a good fit to answer that broad of a question either! – Shepmaster Apr 24 '15 at 02:24
  • You're right, it was a very broad question. Thanks for being patient. @huon-dbaupp got it spot on though: what I wanted to know was how to create an image, edit it and save it out. The procedural stuff can come later. Thanks again. – Rik Apr 24 '15 at 07:29

2 Answers2

17

The place to begin is the docs and the repository.

It's not immediately obvious from the landing page of the documentation, but the core type in image is ImageBuffer.

The new function allows one to construct an ImageBuffer representing an image with the given/width, storing pixels of a given type (e.g. RGB, or that with transparency). One can use methods like pixels_mut, get_pixel_mut and put_pixel (the latter are below pixels_mut in the documentation) to modify the image. E.g.

extern crate image;

use image::{ImageBuffer, Rgb};

const WIDTH: u32 = 10;
const HEIGHT: u32 = 10;

fn main() {
    // a default (black) image containing Rgb values
    let mut image = ImageBuffer::<Rgb<u8>>::new(WIDTH, HEIGHT);

    // set a central pixel to white
    image.get_pixel_mut(5, 5).data = [255, 255, 255];

    // write it out to a file
    image.save("output.png").unwrap();
}

which looks like: output

The repo is particularly useful as a starting point, because it contains examples, in particular, it has an example of programmatically generating an image. When using a new library, I'll open the docs, and, if confused, the repo specifically to look for examples.

NOTE:

get_pixel_mut Deprecated since 0.24.0: Use get_pixel and put_pixel instead.

Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88
huon
  • 94,605
  • 21
  • 231
  • 225
  • On a side note, I wish things like "elmesque" where implemented against "rust-image" instead of requiring the more desktop-oriented parts of the Piston. – ArtemGr Apr 24 '15 at 10:52
  • Thanks a lot! that was the example that was missing in the documentation to get running! – Tristram Gräbener Dec 23 '15 at 15:18
  • 8
    This code wont' compile because now `Imagebuffer` requires two arguments: pixel type and container to store it. You should change to, for example, `let mut image = ImageBuffer::, Vec >::new(WIDTH, HEIGHT);` – Month Nov 19 '16 at 15:07
  • 2
    I get "expected 2 parameters" for `.save()` using `image 0.15.0`. I can't get the function to work. Also tried `image.save("out.png", image::PNG)` and `image.save(&Path::new("out.png), image::PNG)` :( – Niklas R Aug 09 '17 at 16:08
6

As @huon answer is 6 years old, I was getting errors reproducing the result, so I wrote this,

use image::{ImageBuffer, RgbImage};

const WIDTH:u32 = 10;
const HEIGHT:u32 = 10;

fn main() {
    let mut image: RgbImage = ImageBuffer::new(WIDTH, HEIGHT);
    *image.get_pixel_mut(5, 5) = image::Rgb([255,255,255]);
    image.save("output.png").unwrap();
}
Eka
  • 14,170
  • 38
  • 128
  • 212
  • In order not to conflict with `ImageBuffer` changes, it is better to construct the instance of `RgbImage` directly: `let mut image: RgbImage = RgbImage::new(WIDTH, HEIGHT);` – Kaplan Sep 27 '22 at 14:34