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_y in img_y1..img_y2 { for px_x in img_x1..img_x2 { 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 y in 0..(img_y2 - img_y1) { for x in 0..(img_x2 - img_x1) { 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(); }