From 599fb095036314e1528520084107c652c8681bdc Mon Sep 17 00:00:00 2001 From: saji Date: Tue, 30 Jul 2024 08:53:47 -0500 Subject: [PATCH] add palette selection; make image request extractor --- src/api.rs | 36 +++++++++++++++++++++--------------- src/imageproc.rs | 24 ++++++++++++++---------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/api.rs b/src/api.rs index c590007..f871e0b 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,11 +1,12 @@ use crate::display::EInkPanel; use crate::imageproc::{DitherMethod, DitherPalette, EInkImage}; -use axum::extract::Multipart; +use axum::async_trait; +use axum::extract::{FromRequest, Multipart, State}; use axum::http::{header, StatusCode}; use axum::response::IntoResponse; -use axum::{extract::State, response::Response, routing::post, Router}; +use axum::{response::Response, routing::post, Router}; use image::{ImageReader, RgbImage}; -use std::io::{BufWriter, Cursor}; +use std::io::Cursor; use std::str; use std::str::FromStr; use std::sync::Arc; @@ -98,8 +99,15 @@ struct ImageRequest { palette: DitherPalette, } -impl ImageRequest { - async fn from_multipart(mut parts: Multipart) -> Result { +#[async_trait] +impl FromRequest for ImageRequest +where + S: Send + Sync, +{ + type Rejection = AppError; + + async fn from_request(req: axum::extract::Request, state: &S) -> Result { + let mut parts = Multipart::from_request(req, state).await?; let mut img = None; let mut palette = None; let mut dither_method = None; @@ -141,13 +149,12 @@ impl ImageRequest { #[instrument(skip(ctx))] async fn set_image( State(ctx): State, - parts: Multipart, + img_req: ImageRequest, ) -> Result { - let call = ImageRequest::from_multipart(parts).await?; - let mut buf = EInkImage::new(call.palette.value().to_vec()); + let mut buf = EInkImage::new(img_req.palette.value().to_vec()); { - let mut dither = call.dither_method.get_ditherer(); - dither.dither(&call.image, &mut buf); + let mut dither = img_req.dither_method.get_ditherer(); + dither.dither(&img_req.image, &mut buf); } let cmd = DisplaySetCommand { img: Box::new(buf) }; ctx.display_channel @@ -158,12 +165,11 @@ async fn set_image( /// generates a dithered image based on the given image and the dithering parameters. /// Can be used to see how the dithering and palette choices affect the result. -async fn preview_image(parts: Multipart) -> Result { - let call = ImageRequest::from_multipart(parts).await?; - let mut buf = EInkImage::new(call.palette.value().to_vec()); +async fn preview_image(img_req: ImageRequest) -> Result { + let mut buf = EInkImage::new(img_req.palette.value().to_vec()); { - let mut dither = call.dither_method.get_ditherer(); - dither.dither(&call.image, &mut buf); + let mut dither = img_req.dither_method.get_ditherer(); + dither.dither(&img_req.image, &mut buf); } // Convert buf into a png image. let img = buf.into_rgbimage(); diff --git a/src/imageproc.rs b/src/imageproc.rs index b60e11b..302359d 100644 --- a/src/imageproc.rs +++ b/src/imageproc.rs @@ -21,12 +21,12 @@ const DISPLAY_PALETTE: [Srgb; 7] = [ ]; const SIMPLE_PALETTE: [Srgb; 7] = [ - Srgb::new(0.0,0.0,0.0), // Black - Srgb::new(1.0,1.0,1.0), // White - Srgb::new(0.0, 1.0, 0.0), // Green - Srgb::new(0.0, 0.0, 1.0), // Blue - Srgb::new(1.0, 0.0, 0.0), // Red - Srgb::new(1.0, 1.0, 0.0), // Yellow + Srgb::new(0.0, 0.0, 0.0), // Black + Srgb::new(1.0, 1.0, 1.0), // White + Srgb::new(0.0, 1.0, 0.0), // Green + Srgb::new(0.0, 0.0, 1.0), // Blue + Srgb::new(1.0, 0.0, 0.0), // Red + Srgb::new(1.0, 1.0, 0.0), // Yellow Srgb::new(0.757, 0.443, 0.165), // Orange ]; @@ -37,10 +37,11 @@ pub enum DitherPalette { } impl DitherPalette { - pub fn value(&self) -> &[Srgb] { + #[must_use] + pub const fn value(&self) -> &[Srgb] { match self { Self::Default => &DISPLAY_PALETTE, - Self::Simple => &DISPLAY_PALETTE, // FIXME: use simple pallete based on binary. + Self::Simple => &SIMPLE_PALETTE, // FIXME: use simple pallete based on binary. } } } @@ -94,7 +95,10 @@ impl EInkImage { pub fn into_rgbimage(&self) -> RgbImage { RgbImage::from_fn(self.buf.width(), self.buf.height(), |x, y| { let idx = self.buf.get_pixel(x, y).0[0]; - let disp_color = self.palette.get(idx as usize).unwrap(); + let disp_color = self + .palette + .get(idx as usize) + .expect("Palette will never be out of bounds"); let arr: [u8; 3] = disp_color.into_format().into(); imgRgb(arr) }) @@ -174,7 +178,7 @@ fn compute_error_adjusted_color(orig: &Lab, err: &Lab, weight: f32) -> Lab { /// ``DiffusionPoint`` is part of the diffusion matrix, represented by a shift in x and y and an error /// scaling factor. #[derive(Debug)] -struct DiffusionPoint { +pub struct DiffusionPoint { xshift: i32, yshift: i32, scale: f32,