pixelize/
lib.rs

1use image::{imageops, FilterType, GenericImageView, ImageBuffer, ImageError, RgbaImage};
2use std::io::Cursor;
3
4pub struct Options {
5  pub degree: u32,
6  pub preserve_size: bool,
7}
8
9pub fn pixelize(buf: &[u8], opts: &Options) -> Result<RgbaImage, ImageError> {
10  let format = image::guess_format(buf)?;
11  let c = Cursor::new(buf);
12  let img = image::load(c, format).unwrap();
13  let (w, h) = img.dimensions();
14  if opts.degree >= w || opts.degree >= h {
15    return Err(ImageError::UnsupportedError(String::from(
16      "degree cannot exceed the dimensions of the image!",
17    )));
18  }
19
20  if opts.degree <= 1 {
21    return Err(ImageError::UnsupportedError(String::from(
22      "degree needs to be > 1!",
23    )));
24  }
25
26  let mut out: RgbaImage = ImageBuffer::new(w / opts.degree, h / opts.degree);
27  let (new_w, new_h) = out.dimensions();
28  for x in 0..new_w {
29    for y in 0..new_h {
30      let p = img.get_pixel(x * opts.degree, y * opts.degree);
31      out.put_pixel(x, y, p);
32    }
33  }
34
35  if opts.preserve_size {
36    out = imageops::resize(&out, w, h, FilterType::Nearest);
37  }
38
39  return Ok(out);
40}