add palette selection; make image request extractor

This commit is contained in:
saji 2024-07-30 08:53:47 -05:00
parent c7e57f3d3b
commit 599fb09503
2 changed files with 35 additions and 25 deletions

View file

@ -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<Self, AppError> {
#[async_trait]
impl<S> FromRequest<S> for ImageRequest
where
S: Send + Sync,
{
type Rejection = AppError;
async fn from_request(req: axum::extract::Request, state: &S) -> Result<Self, Self::Rejection> {
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<Context>,
parts: Multipart,
img_req: ImageRequest,
) -> Result<impl IntoResponse, AppError> {
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<impl IntoResponse, AppError> {
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<impl IntoResponse, AppError> {
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();

View file

@ -21,8 +21,8 @@ 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, 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
@ -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,