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