Initial commit
This commit is contained in:
commit
7e974d42ae
12 changed files with 232 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
use nix
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/.direnv
|
||||||
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imgsyn"
|
||||||
|
version = "0.1.0"
|
||||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "imgsyn"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
3
main.rs
Normal file
3
main.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
||||||
12
shell.nix
Normal file
12
shell.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
pkgs.mkShell {
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
rustfmt
|
||||||
|
cargo
|
||||||
|
clippy
|
||||||
|
rustc
|
||||||
|
ffmpeg
|
||||||
|
imagemagick
|
||||||
|
rust-analyzer
|
||||||
|
];
|
||||||
|
}
|
||||||
56
src/canvas.rs
Normal file
56
src/canvas.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
use crate::{ImgSyn, pixel::Pixel};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub struct Canvas {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub default_px: Pixel,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct PaintedCanvas {
|
||||||
|
pub meta: Canvas,
|
||||||
|
pub array: Vec<Vec<Pixel>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Canvas {
|
||||||
|
pub fn new(width: u32, height: u32, default_px: Pixel) -> Self {
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
default_px,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImgSyn for Canvas {
|
||||||
|
fn getpx(&self, _meta: Canvas, _x: f32, _y: f32) -> Pixel {
|
||||||
|
self.default_px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaintedCanvas {
|
||||||
|
pub fn new(meta @ Canvas { width, height, .. }: Canvas, function: impl ImgSyn) -> Self {
|
||||||
|
Self {
|
||||||
|
meta,
|
||||||
|
array: (0..width)
|
||||||
|
.map(|x| x as f32 / width as f32)
|
||||||
|
.map(|x| {
|
||||||
|
(0..height)
|
||||||
|
.map(|y| y as f32 / height as f32)
|
||||||
|
.map(|y| function.getpx(meta, x, y))
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImgSyn for PaintedCanvas {
|
||||||
|
fn getpx(&self, meta: Canvas, x: f32, y: f32) -> Pixel {
|
||||||
|
// float coords -> int coords
|
||||||
|
let x = (x * meta.width as f32).round() as usize;
|
||||||
|
let y = (y * meta.height as f32).round() as usize;
|
||||||
|
self.array[x][y]
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/lib.rs
Normal file
36
src/lib.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
mod canvas;
|
||||||
|
pub mod ops;
|
||||||
|
mod pixel;
|
||||||
|
mod pixfn;
|
||||||
|
|
||||||
|
pub use canvas::*;
|
||||||
|
pub use pixel::*;
|
||||||
|
pub use pixfn::*;
|
||||||
|
|
||||||
|
use crate::ops::ImgSynMap;
|
||||||
|
|
||||||
|
pub trait ImgSynPixFn: Clone {
|
||||||
|
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ImgSyn: Clone {
|
||||||
|
fn getpx(&self, meta: Canvas, x: f32, y: f32) -> Pixel;
|
||||||
|
fn map<F: ImgSynPixFn>(self, f: F) -> ImgSynMap<Self, F> {
|
||||||
|
ImgSynMap(self, f)
|
||||||
|
}
|
||||||
|
fn paint(self, meta: Canvas) -> PaintedCanvas {
|
||||||
|
PaintedCanvas::new(meta, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::{Canvas, ImgSyn, PixFnFloat, Pixel};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
Canvas::new(100, 100, Pixel::new_black())
|
||||||
|
.map(PixFnFloat(|_, x, y, pix| pix.with_r(x).with_g(y)))
|
||||||
|
.map(PixFnFloat(|_, _, _, pix| pix.with_b(1.0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/ops/map.rs
Normal file
10
src/ops/map.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
use crate::{ImgSyn, ImgSynPixFn};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ImgSynMap<Prev: ImgSyn, F: ImgSynPixFn>(pub(crate) Prev, pub(crate) F);
|
||||||
|
|
||||||
|
impl<Prev: ImgSyn, F: ImgSynPixFn> ImgSyn for ImgSynMap<Prev, F> {
|
||||||
|
fn getpx(&self, meta: crate::Canvas, x: f32, y: f32) -> crate::Pixel {
|
||||||
|
self.1.run(meta, x, y, self.0.getpx(meta, x, y))
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/ops/mod.rs
Normal file
2
src/ops/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod map;
|
||||||
|
pub use map::*;
|
||||||
69
src/pixel.rs
Normal file
69
src/pixel.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub struct Pixel {
|
||||||
|
r: f32,
|
||||||
|
g: f32,
|
||||||
|
b: f32,
|
||||||
|
a: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pixel {
|
||||||
|
pub fn new_blank_black() -> Pixel {
|
||||||
|
Self::new_black().with_a(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_blank_white() -> Pixel {
|
||||||
|
Self::new_white().with_a(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_white() -> Pixel {
|
||||||
|
Self {
|
||||||
|
r: 1.0,
|
||||||
|
g: 1.0,
|
||||||
|
b: 1.0,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_black() -> Pixel {
|
||||||
|
Self {
|
||||||
|
r: 0.0,
|
||||||
|
g: 0.0,
|
||||||
|
b: 0.0,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_r(self, x: f32) -> Pixel {
|
||||||
|
Self { r: x, ..self }
|
||||||
|
}
|
||||||
|
pub fn with_g(self, x: f32) -> Pixel {
|
||||||
|
Self { g: x, ..self }
|
||||||
|
}
|
||||||
|
pub fn with_b(self, x: f32) -> Pixel {
|
||||||
|
Self { b: x, ..self }
|
||||||
|
}
|
||||||
|
pub fn with_a(self, x: f32) -> Pixel {
|
||||||
|
Self { a: x, ..self }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map(self, f: impl FnOnce(Self) -> Pixel) -> Pixel {
|
||||||
|
f(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_r(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
|
||||||
|
self.r = f(self.r);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn map_g(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
|
||||||
|
self.r = f(self.r);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn map_b(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
|
||||||
|
self.r = f(self.r);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn map_a(mut self, f: impl FnOnce(f32) -> f32) -> Pixel {
|
||||||
|
self.r = f(self.r);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/pixfn.rs
Normal file
28
src/pixfn.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
use crate::{Canvas, ImgSynPixFn, Pixel};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct PixFnInt<T: (Fn(Canvas, u32, u32, Pixel) -> Pixel) + Copy>(pub T);
|
||||||
|
impl<T> ImgSynPixFn for PixFnInt<T>
|
||||||
|
where
|
||||||
|
T: (Fn(Canvas, u32, u32, Pixel) -> Pixel) + Copy,
|
||||||
|
{
|
||||||
|
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel {
|
||||||
|
self.0(
|
||||||
|
meta,
|
||||||
|
(x * meta.width as f32).round() as u32,
|
||||||
|
(y * meta.height as f32).round() as u32,
|
||||||
|
pixel,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct PixFnFloat<T: (Fn(Canvas, f32, f32, Pixel) -> Pixel) + Copy>(pub T);
|
||||||
|
impl<T> ImgSynPixFn for PixFnFloat<T>
|
||||||
|
where
|
||||||
|
T: (Fn(Canvas, f32, f32, Pixel) -> Pixel) + Copy,
|
||||||
|
{
|
||||||
|
fn run(&self, meta: Canvas, x: f32, y: f32, pixel: Pixel) -> Pixel {
|
||||||
|
self.0(meta, x, y, pixel)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue