add position matrix

This commit is contained in:
Schrottkatze 2024-05-22 09:42:40 +02:00
parent 238519ee90
commit 4861d93c80
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
3 changed files with 38 additions and 15 deletions

View file

@ -5,10 +5,12 @@ pub fn mat_editor<const R: usize, const C: usize>(
ui: &mut egui::Ui, ui: &mut egui::Ui,
mat: &mut SMatrix<f32, R, C>, mat: &mut SMatrix<f32, R, C>,
id: &str, id: &str,
skip_last: bool,
) -> egui::Response { ) -> egui::Response {
egui::Grid::new(id) egui::Grid::new(id)
.show(ui, |ui| { .show(ui, |ui| {
mat.row_iter_mut().enumerate().for_each(|(i, mut row)| { mat.row_iter_mut().enumerate().for_each(|(i, mut row)| {
if !skip_last || i + 1 < R {
row.iter_mut().for_each(|item| { row.iter_mut().for_each(|item| {
ui.add( ui.add(
egui::DragValue::new(item) egui::DragValue::new(item)
@ -17,6 +19,7 @@ pub fn mat_editor<const R: usize, const C: usize>(
); );
}); });
ui.end_row(); ui.end_row();
}
}) })
}) })
.response .response

View file

@ -5,14 +5,14 @@ use std::{
use eframe::egui::{self, TextureOptions}; use eframe::egui::{self, TextureOptions};
use image::{DynamicImage, Pixel, Rgb, Rgb32FImage}; use image::{DynamicImage, Pixel, Rgb, Rgb32FImage};
use nalgebra::{SMatrix, Vector4}; use nalgebra::{SMatrix, Vector3, Vector4};
use rayon::prelude::*; use rayon::prelude::*;
use image::EncodableLayout; use image::EncodableLayout;
struct ProcessorInstruction { struct ProcessorInstruction {
img: Arc<Rgb32FImage>, img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>, color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>, pos_matrix: SMatrix<f32, 3, 3>,
ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>, ret: oneshot::Sender<(egui::TextureHandle, (f32, f32))>,
ctx: egui::Context, ctx: egui::Context,
handle: Option<egui::TextureHandle>, handle: Option<egui::TextureHandle>,
@ -37,7 +37,27 @@ impl Processor {
{ {
let (width, height) = img.dimensions(); 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) { if !color_matrix.is_identity(f32::EPSILON) {
r.par_pixels_mut().for_each(|px| { r.par_pixels_mut().for_each(|px| {
*px = Rgb::from( *px = Rgb::from(
@ -76,7 +96,7 @@ impl Processor {
&self, &self,
img: Arc<Rgb32FImage>, img: Arc<Rgb32FImage>,
color_matrix: SMatrix<f32, 3, 4>, color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>, pos_matrix: SMatrix<f32, 3, 3>,
ctx: egui::Context, ctx: egui::Context,
handle: Option<egui::TextureHandle>, handle: Option<egui::TextureHandle>,
) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> { ) -> oneshot::Receiver<(egui::TextureHandle, (f32, f32))> {

View file

@ -16,7 +16,7 @@ mod img_processor;
pub struct App { pub struct App {
color_matrix: SMatrix<f32, 3, 4>, color_matrix: SMatrix<f32, 3, 4>,
pos_matrix: SMatrix<f32, 2, 3>, pos_matrix: SMatrix<f32, 3, 3>,
file_dialog: FileDialog, file_dialog: FileDialog,
new_file: Option<PathBuf>, new_file: Option<PathBuf>,
cur_img: Option<Arc<Rgb32FImage>>, cur_img: Option<Arc<Rgb32FImage>>,
@ -74,11 +74,11 @@ impl eframe::App for App {
let old_pos_mat = self.pos_matrix; let old_pos_mat = self.pos_matrix;
ui.label("Color Matrix Editor"); ui.label("Color Matrix Editor");
let color_mat_edited = 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.add_space(8.);
ui.label("Position Matrix Editor"); ui.label("Position Matrix Editor");
let pos_mat_edited = 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; mats_changed |= old_color_mat == self.color_matrix || old_pos_mat == self.pos_matrix;
if mats_changed if mats_changed