You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
2.2 KiB
64 lines
2.2 KiB
use image::{Rgb, GenericImage};
|
|
|
|
pub const NCOLORS: usize = 3;
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[repr(C)]
|
|
pub struct Transform {
|
|
pub color_matrix: [f32; NCOLORS * NCOLORS],
|
|
// TODO: make these f32s
|
|
pub from_corner: (u32, u32),
|
|
pub from_extents: (u32, u32),
|
|
pub to_corner: (f32, f32),
|
|
pub to_extents: [(f32, f32); 2],
|
|
}
|
|
|
|
impl Transform {
|
|
pub fn apply_add<I: GenericImage<Pixel=Rgb<f32>>, O: GenericImage<Pixel=Rgb<f32>>>(&self, input: &I, output: &mut O, dims: (u32, u32), c: f32) {
|
|
for x_off in 0..self.from_extents.0 {
|
|
let x = x_off as f32 / self.from_extents.0 as f32;
|
|
for y_off in 0..self.from_extents.1 {
|
|
let y = y_off as f32 / self.from_extents.1 as f32;
|
|
let x_in = (self.to_corner.0 + x * self.to_extents[0].0 + y * self.to_extents[0].1) * dims.0 as f32;
|
|
let y_in = (self.to_corner.1 + x * self.to_extents[1].0 + y * self.to_extents[1].1) * dims.1 as f32;
|
|
let in_coords = (x_in, y_in);
|
|
|
|
// Get input color from pixels near sample
|
|
let mut in_pix = [0.0; NCOLORS];
|
|
let in_coords_i32 = (in_coords.0.floor() as i32, in_coords.1.floor() as i32);
|
|
for x in in_coords_i32.0..=in_coords_i32.0 + 1 {
|
|
for y in in_coords_i32.1..=in_coords_i32.1 + 1 {
|
|
if x < 0 || y < 0 || x >= dims.0 as i32 || y >= dims.1 as i32 {
|
|
continue;
|
|
}
|
|
let val = input.get_pixel(x as u32, y as u32).0;
|
|
let frac = (x as f32 - in_coords.0, y as f32 - in_coords.1);
|
|
let area = (1.0 - frac.0.abs()) * (1.0 - frac.1.abs());
|
|
for i in 0..NCOLORS {
|
|
in_pix[i] += val[i] * area;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Compute the transformed color
|
|
let mut color = [0.0; NCOLORS];
|
|
for i in 0..NCOLORS {
|
|
for j in 0..NCOLORS {
|
|
color[i] += self.color_matrix[i * NCOLORS + j] * in_pix[j];
|
|
}
|
|
}
|
|
|
|
// Put the resulting color into the output image
|
|
let x_out = self.from_corner.0 + x_off;
|
|
let y_out = self.from_corner.1 + y_off;
|
|
let mut pix = output.get_pixel(x_out, y_out).0;
|
|
for i in 0..NCOLORS {
|
|
pix[i] += color[i] * c;
|
|
}
|
|
output.put_pixel(x_out, y_out, Rgb(pix));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|