arko 0.2.4

A small library for pixel manipulation in images
Documentation
use crate::io::IO;
use crate::validator;
use image::GenericImageView;
use rand::Rng;

fn build_brush<'a>(io: IO<'a>, proba: i32, min: i32, max: i32) -> Brush<'a> {
    let brush = Brush {
        min,
        max,
        proba,
        io,
    };
    brush.validate_attributes();
    brush
}

pub fn bottom_to_top(io: IO, proba: i32, min: i32, max: i32) {
    let brush = build_brush(io, proba, min, max);
    brush.bottom_to_top()
}

pub fn left_to_right(io: IO, proba: i32, min: i32, max: i32) {
    let brush = build_brush(io, proba, min, max);
    brush.left_to_right()
}

pub fn right_to_left(io: IO, proba: i32, min: i32, max: i32) {
    let brush = build_brush(io, proba, min, max);
    brush.right_to_left()
}

pub fn top_to_bottom(io: IO, proba: i32, min: i32, max: i32) {
    let brush = build_brush(io, proba, min, max);
    brush.top_to_bottom()
}

struct Brush<'a> {
    min: i32,
    max: i32,
    proba: i32,
    io: IO<'a>,
}

impl<'a> Brush<'a> {
    fn validate_attributes(&self) {
        validator::percent("probability", self.proba);
        validator::min_max(self.min, self.max);
    }

    fn bottom_to_top(&self) {
        let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());

        let mut rng = rand::thread_rng();
        let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
        let mut color = self.io.in_img.get_pixel(1, 1);
        for h in 0..(self.io.in_img.height() - 1) {
            for w in 0..(self.io.in_img.width() - 1) {
                new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
            }
        }
        for w in 1..(self.io.in_img.width() - 1) {
            for h in 1..(self.io.in_img.height() - 2) {
                let inverted_w = self.io.in_img.width() - 1 - w;
                let inverted_h = self.io.in_img.height() - 2 - h;
                if pixel_to_glitch > 0 {
                    pixel_to_glitch = pixel_to_glitch - 1;
                    new_img.put_pixel(inverted_w, inverted_h, color);
                } else {
                    if rng.gen_range(0..100) < self.proba {
                        pixel_to_glitch = rng.gen_range(self.min..self.max);
                        color = *new_img.get_pixel(inverted_w + 1, inverted_h);
                        new_img.put_pixel(w, h, color);
                    }
                }
            }
        }
        new_img.save(self.io.out_img).unwrap();
    }

    fn left_to_right(&self) {
        let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());

        let mut rng = rand::thread_rng();
        let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
        let mut color = self.io.in_img.get_pixel(1, 1);

        for h in 0..(self.io.in_img.height() - 1) {
            for w in 0..(self.io.in_img.width() - 1) {
                new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
            }
        }

        for h in 1..(self.io.in_img.height() - 1) {
            for w in 2..(self.io.in_img.width() - 1) {
                if pixel_to_glitch > 0 {
                    pixel_to_glitch = pixel_to_glitch - 1;
                    new_img.put_pixel(w, h, color);
                } else {
                    if rng.gen_range(0..100) < self.proba {
                        pixel_to_glitch = rng.gen_range(self.min..self.max);
                        color = *new_img.get_pixel(w - 2, h - 1);
                        new_img.put_pixel(w, h, color);
                    }
                }
            }
        }
        new_img.save(self.io.out_img).unwrap();
    }

    fn right_to_left(&self) {
        let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());

        let mut rng = rand::thread_rng();
        let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
        let mut color = self.io.in_img.get_pixel(1, 1);
        for h in 0..(self.io.in_img.height() - 1) {
            for w in 0..(self.io.in_img.width() - 1) {
                new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
            }
        }
        for h in 1..(self.io.in_img.height() - 1) {
            for w in 1..(self.io.in_img.width() - 2) {
                let inverted_w = self.io.in_img.width() - 2 - w;
                let inverted_h = self.io.in_img.height() - 1 - h;
                if pixel_to_glitch > 0 {
                    pixel_to_glitch = pixel_to_glitch - 1;
                    new_img.put_pixel(inverted_w, inverted_h, color);
                } else {
                    if rng.gen_range(0..100) < self.proba {
                        pixel_to_glitch = rng.gen_range(self.min..self.max);
                        color = *new_img.get_pixel(inverted_w, inverted_h + 1);
                        new_img.put_pixel(w, h, color);
                    }
                }
            }
        }
        new_img.save(self.io.out_img).unwrap();
    }

    fn top_to_bottom(&self) {
        let mut new_img = image::ImageBuffer::new(self.io.in_img.width(), self.io.in_img.height());

        let mut rng = rand::thread_rng();
        let mut pixel_to_glitch = rng.gen_range(self.min..self.max);
        let mut color = self.io.in_img.get_pixel(0, 0);

        for h in 0..(self.io.in_img.height() - 1) {
            for w in 0..(self.io.in_img.width() - 1) {
                new_img.put_pixel(w, h, self.io.in_img.get_pixel(w, h));
            }
        }

        for w in 1..(self.io.in_img.width() - 1) {
            for h in 2..(self.io.in_img.height() - 1) {
                if pixel_to_glitch > 0 {
                    pixel_to_glitch = pixel_to_glitch - 1;
                    new_img.put_pixel(w, h, color);
                } else {
                    if rng.gen_range(0..100) < self.proba {
                        pixel_to_glitch = rng.gen_range(self.min..self.max);
                        color = *new_img.get_pixel(w - 1, h - 2);
                        new_img.put_pixel(w, h, color);
                    }
                }
            }
        }
        new_img.save(self.io.out_img).unwrap();
    }
}