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}