diff --git a/Cargo.toml b/Cargo.toml index adf5d18..efe45a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,10 @@ path = "src/noise-studies-01.rs" name = "noise-studies-02" path = "src/noise-studies-02.rs" +[[bin]] +name = "value-of-values" +path = "src/value-of-values.rs" + [dependencies] nannou = "0.18" rand = "0.8.5" diff --git a/src/value-of-values.rs b/src/value-of-values.rs new file mode 100644 index 0000000..5134b43 --- /dev/null +++ b/src/value-of-values.rs @@ -0,0 +1,102 @@ +use nannou::image::{self, GenericImageView}; +use nannou::prelude::*; +use std::env; + +struct Model { + image: image::DynamicImage, +} + +const WIDTH: u32 = 800; + +fn main() { + nannou::app(model).run(); +} + +fn model(app: &App) -> Model { + app.set_loop_mode(LoopMode::Wait); + app.new_window() + .size(WIDTH, WIDTH) + .view(view) + .build() + .unwrap(); + + let file = env::args().nth(1).ok_or("Please give me a file!").unwrap(); + let image = image::open(file).unwrap(); + + Model { image } +} + +fn view(app: &App, model: &Model, frame: Frame) { + let _block_size: usize = 32; + let draw = app + .draw() + .translate(vec3(WIDTH as f32 / 2.0, WIDTH as f32 / 2.0, 0.0)) + .scale(-1.0); + + let win = app.window_rect(); + let tile_count = map_range( + clamp(app.mouse.x, WIDTH as f32 / -2.0, WIDTH as f32 / 2.0), + WIDTH as f32 / -2.0, + WIDTH as f32 / 2.0, + WIDTH / 4, + WIDTH / 20, + ); + + let rect_size = win.w() / tile_count as f32; + + let scale_x = model.image.width() as f32 / win.w(); + let scale_y = model.image.height() as f32 / win.h(); + + for grid_y in 0..tile_count as usize { + for grid_x in 0..tile_count as usize { + let pos_x = grid_x as f32 * rect_size; + let pos_y = grid_y as f32 * rect_size; + + let img_x1 = (pos_x * scale_x) as u32; + let img_y1 = (pos_y * scale_y) as u32; + let img_x2 = ((pos_x + rect_size - 1.0) * scale_x) as u32; + let img_y2 = ((pos_y + rect_size - 1.0) * scale_y) as u32; + + // extract colors from current rect + let mut cols: Vec = Vec::new(); + for px_x in img_x1..img_x2 { + for px_y in img_y1..img_y2 { + let px = model.image.get_pixel(px_x, px_y); + let col = rgb( + px[0] as f32 / 255.0, + px[1] as f32 / 255.0, + px[2] as f32 / 255.0, + ); + cols.push(col.clone().into()); + } + } + + // sort colors + cols.sort_by(|a, b| { + a.hue + .to_radians() + .partial_cmp(&b.hue.to_radians()) + .unwrap() + .reverse() + }); + + // draw sorted colors + for px_x in img_x1..img_x2 { + for px_y in img_y1..img_y2 { + let x = px_x - img_x1; + let y = px_y - img_y1; + let i = (x * (rect_size as u32) + y) as usize; + + let pos_x = pos_x + (rect_size * (x as f32 / rect_size)); + let pos_y = pos_y + (rect_size * (y as f32 / rect_size)); + draw.rect() + .x_y(pos_x, pos_y) // rects get drawn from the middle + .w_h(1.0, 1.0) + .color(cols[i]); + } + } + } + } + + draw.to_frame(app, &frame).unwrap(); +}