From 3493a7cc78252e8d047516b4c7b4130537f911be Mon Sep 17 00:00:00 2001 From: heyarne Date: Mon, 3 Oct 2022 23:24:24 +0200 Subject: [PATCH] Broken: Refactor grid code into `parcellize` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason the updated pixel buffer isn't drawn? Or the pixel buffer isn't completely updated? išŸ¤” --- src/value-of-values.rs | 187 +++++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 71 deletions(-) diff --git a/src/value-of-values.rs b/src/value-of-values.rs index b042035..03629c7 100644 --- a/src/value-of-values.rs +++ b/src/value-of-values.rs @@ -1,9 +1,15 @@ -use nannou::image::{self, GenericImageView}; +use nannou::image::{self, GenericImage, GenericImageView}; use nannou::prelude::*; use std::env; +struct Parcels { + rect_size: u32, + texture: wgpu::Texture, +} + struct Model { image: image::DynamicImage, + parcellized: Parcels, } const WIDTH: u32 = 800; @@ -12,11 +18,88 @@ fn main() { nannou::app(model).run(); } +fn parcellize(app: &App, img: &image::DynamicImage, rect_size: u32) -> wgpu::Texture { + let start = std::time::Instant::now(); + println!("Called parcellize…"); + + let win = app.window_rect(); + let tile_count = win.w() as u32 / rect_size; + + let scale_x = img.width() / win.w() as u32; + let scale_y = img.height() / win.h() as u32; + eprintln!("scale: {:?}", (scale_x, scale_y)); + + let img = img.to_owned(); + let mut parcels = img.clone(); + + eprintln!( + "before iterating: {:?}, {:?}, {:?}", + parcels.get_pixel(0, 0), + parcels.get_pixel(100, 100), + parcels.get_pixel(parcels.width() - 1, parcels.height() - 1) + ); + for grid_y in 0..tile_count { + for grid_x in 0..tile_count { + // eprintln!("Iteration: {:?}", start.elapsed()); + let iter = std::time::Instant::now(); + let x = grid_x * rect_size; + let y = grid_y * rect_size; + + // extract colors from current rect; note that we're working in + // image coordinates here! + let img_x = (x * scale_x) as u32; + let img_y = (y * scale_y) as u32; + let img_rect = rect_size * scale_x as u32; + let crop = img.view(img_x, img_y, img_rect, img_rect); + let mut colors: Vec<_> = crop.pixels().map(|(_, _, px)| px).collect(); + + // eprintln!("get_pixels: {:?}", iter.elapsed()); + + // sort colors + colors.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + + // eprintln!("sorted: {:?}", iter.elapsed()); + // eprintln!( + // "crop: {:?} {:?}", + // crop.pixels().into_iter().nth(0), + // crop.pixels().into_iter().last() + // ); + // eprintln!("colors: {:?} {:?}", colors.first(), colors.last()); + + // // draw sorted colors + // crop.pixels().enumerate().for_each(|(i, (_, _, rgba))| { + // parcels.put_pixel(x + i as u32 % (rect_size * scale_x), y, rgba); + // }); + // + + // eprintln!("before put pixel: {:?}", parcels.get_pixel(x, y)); + colors.iter().enumerate().for_each(|(i, col)| { + let i = i as u32; + let x_off = i % rect_size; + let y_off = i / rect_size; + // let (r, g, b) = col.into_components(); + parcels.put_pixel(x + x_off, y + y_off, *col); //image::Rgba::from([r, g, b, 255])); + }); + // eprintln!("after put pixel: {:?}", parcels.get_pixel(x, y)); + // eprintln!("put_pixels: {:?}", iter.elapsed()); + } + } + eprintln!( + "after iterating: {:?}, {:?}, {:?}", + parcels.get_pixel(0, 0), + parcels.get_pixel(100, 100), + parcels.get_pixel(parcels.width() - 1, parcels.height() - 1) + ); + + wgpu::Texture::from_image(app, &parcels) +} + fn model(app: &App) -> Model { - app.set_loop_mode(LoopMode::Wait); + // app.set_loop_mode(LoopMode::Wait); app.new_window() .size(WIDTH, WIDTH) .view(view) + .mouse_moved(mouse_moved) .build() .unwrap(); @@ -24,77 +107,39 @@ fn model(app: &App) -> Model { let image = image::open(file).expect(format!("Could not open image, please check the path.").as_str()); - Model { image } + let rect_size = app.window_rect().w() as u32 / 20; + let parcellized = parcellize(&app, &image, rect_size); + + Model { + image, + parcellized: Parcels { + rect_size, + texture: parcellized, + }, + } +} + +fn mouse_moved(app: &App, model: &mut Model, mouse: Vec2) { + let tile_count = map_range( + clamp(mouse.x, WIDTH as f32 / -2.0, WIDTH as f32 / 2.0), + WIDTH as f32 / -2.0, + WIDTH as f32 / 2.0, + 4, + 20, + ); + + let rect_size = app.window_rect().w() as u32 / tile_count; + if rect_size != model.parcellized.rect_size { + model.parcellized = Parcels { + rect_size, + texture: parcellize(&app, &model.image, rect_size), + }; + } } 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]); - } - } - } - } - + frame.clear(BLACK); + let draw = app.draw(); + draw.texture(&model.parcellized.texture); draw.to_frame(app, &frame).unwrap(); }