diff --git a/src/components.rs b/src/components.rs index 1212ab6..28f23af 100644 --- a/src/components.rs +++ b/src/components.rs @@ -5,18 +5,21 @@ pub fn mat_editor( ui: &mut egui::Ui, mat: &mut SMatrix, id: &str, + skip_last: bool, ) -> egui::Response { egui::Grid::new(id) .show(ui, |ui| { mat.row_iter_mut().enumerate().for_each(|(i, mut row)| { - row.iter_mut().for_each(|item| { - ui.add( - egui::DragValue::new(item) - .speed(0.01) - .clamp_range(-10.0..=10.0), - ); - }); - ui.end_row(); + if !skip_last || i + 1 < R { + row.iter_mut().for_each(|item| { + ui.add( + egui::DragValue::new(item) + .speed(0.01) + .clamp_range(-10.0..=10.0), + ); + }); + ui.end_row(); + } }) }) .response diff --git a/src/img_processor.rs b/src/img_processor.rs index 265be19..0dfb20a 100644 --- a/src/img_processor.rs +++ b/src/img_processor.rs @@ -5,14 +5,14 @@ use std::{ use eframe::egui::{self, TextureOptions}; use image::{DynamicImage, Pixel, Rgb, Rgb32FImage}; -use nalgebra::{SMatrix, Vector4}; +use nalgebra::{SMatrix, Vector3, Vector4}; use rayon::prelude::*; use image::EncodableLayout; struct ProcessorInstruction { img: Arc, color_matrix: SMatrix, - pos_matrix: SMatrix, + pos_matrix: SMatrix, ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>, ctx: egui::Context, handle: Option, @@ -37,7 +37,27 @@ impl Processor { { let (width, height) = img.dimensions(); - let mut r = (*img).clone(); + // let mut r = (*img).clone(); + let mut r = Rgb32FImage::new(width, height); + if !pos_matrix.is_identity(f32::EPSILON) && pos_matrix.is_invertible() { + let mut inv_mat = pos_matrix.try_inverse().unwrap(); + let mut cols_mut = inv_mat.column_part_mut(2, 2); + *(cols_mut.get_mut(0).unwrap()) *= width as f32; + *(cols_mut.get_mut(1).unwrap()) *= height as f32; + + r.par_enumerate_pixels_mut().for_each(|(x, y, px)| { + let r = inv_mat * Vector3::new(x as f32, y as f32, 1.0); + *px = if r.x.is_sign_positive() && r.y.is_sign_positive() { + *img.get_pixel_checked(r.x as u32, r.y as u32) + .unwrap_or(&Rgb([0., 0., 0.])) + } else { + Rgb([0., 0., 0.]) + }; + }); + } else { + r = (*img).clone() + } + if !color_matrix.is_identity(f32::EPSILON) { r.par_pixels_mut().for_each(|px| { *px = Rgb::from( @@ -76,7 +96,7 @@ impl Processor { &self, img: Arc, color_matrix: SMatrix, - pos_matrix: SMatrix, + pos_matrix: SMatrix, ctx: egui::Context, handle: Option, ) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> { diff --git a/src/lib.rs b/src/lib.rs index 15a9842..f119682 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ mod img_processor; pub struct App { color_matrix: SMatrix, - pos_matrix: SMatrix, + pos_matrix: SMatrix, file_dialog: FileDialog, new_file: Option, cur_img: Option>, @@ -74,11 +74,11 @@ impl eframe::App for App { let old_pos_mat = self.pos_matrix; ui.label("Color Matrix Editor"); let color_mat_edited = - components::mat_editor(ui, &mut self.color_matrix, "color_matrix").dragged(); + components::mat_editor(ui, &mut self.color_matrix, "color_matrix", false).dragged(); ui.add_space(8.); ui.label("Position Matrix Editor"); let pos_mat_edited = - components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix").dragged(); + components::mat_editor(ui, &mut self.pos_matrix, "pos_matrix", true).dragged(); mats_changed |= old_color_mat == self.color_matrix || old_pos_mat == self.pos_matrix; if mats_changed