move display fn to display file, add convert args
This commit is contained in:
parent
ad2426561f
commit
d47a08587c
|
@ -18,7 +18,6 @@ pub trait EInkPanel {
|
||||||
|
|
||||||
pub struct Wrapper {
|
pub struct Wrapper {
|
||||||
spi: SpidevDevice,
|
spi: SpidevDevice,
|
||||||
gpiochip: Chip,
|
|
||||||
delay: Delay,
|
delay: Delay,
|
||||||
panel: Epd7in3f<SpidevDevice, CdevPin, CdevPin, CdevPin, Delay>,
|
panel: Epd7in3f<SpidevDevice, CdevPin, CdevPin, CdevPin, Delay>,
|
||||||
}
|
}
|
||||||
|
@ -54,7 +53,6 @@ impl Wrapper {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
spi,
|
spi,
|
||||||
gpiochip,
|
|
||||||
delay,
|
delay,
|
||||||
panel,
|
panel,
|
||||||
})
|
})
|
||||||
|
@ -91,9 +89,25 @@ impl EInkPanel for FakeEInk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument]
|
||||||
|
pub fn get_display() -> Box<dyn EInkPanel + Send> {
|
||||||
|
match Wrapper::new() {
|
||||||
|
Ok(w) => {
|
||||||
|
info!("Found real hardware, using it");
|
||||||
|
Box::new(w)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Error opening display SPI interface: {e}");
|
||||||
|
warn!("Falling back to fake display");
|
||||||
|
Box::new(FakeEInk {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a thread that can take dithered images and display them. This allows the display to be
|
/// Create a thread that can take dithered images and display them. This allows the display to be
|
||||||
/// used in an async context since updating the display can take ~30 seconds.
|
/// used in an async context since updating the display can take ~30 seconds.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[instrument(skip_all)]
|
||||||
pub fn create_display_thread(
|
pub fn create_display_thread(
|
||||||
mut display: Box<dyn EInkPanel + Send>,
|
mut display: Box<dyn EInkPanel + Send>,
|
||||||
) -> (thread::JoinHandle<()>, mpsc::Sender<Box<DitheredImage>>) {
|
) -> (thread::JoinHandle<()>, mpsc::Sender<Box<DitheredImage>>) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ const SIMPLE_PALETTE: [Srgb; 7] = [
|
||||||
Srgb::new(0.757, 0.443, 0.165), // Orange
|
Srgb::new(0.757, 0.443, 0.165), // Orange
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(strum::EnumString, Serialize, Deserialize, PartialEq, Eq, Debug)]
|
#[derive(strum::EnumString, strum::Display, Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy)]
|
||||||
pub enum Palette {
|
pub enum Palette {
|
||||||
Default,
|
Default,
|
||||||
Simple,
|
Simple,
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -7,12 +7,12 @@ use serde::Deserialize;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
use crate::display::{EInkPanel, FakeEInk, Wrapper};
|
use crate::display::get_display;
|
||||||
use crate::dither::{DitherMethod, DitheredImage};
|
use crate::dither::{DitherMethod, DitheredImage};
|
||||||
use crate::eink::Palette;
|
use crate::eink::Palette;
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
use image::RgbImage;
|
use image::RgbImage;
|
||||||
use tracing::{error, event, info, warn, Level};
|
use tracing::{error, event, info, instrument, warn, Level};
|
||||||
|
|
||||||
/// Application config, including sqlite db path, scan folders, and scheduling.
|
/// Application config, including sqlite db path, scan folders, and scheduling.
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -43,6 +43,8 @@ enum Command {
|
||||||
struct ConvertArgs {
|
struct ConvertArgs {
|
||||||
#[arg(short, long, default_value_t = DitherMethod::NearestNeighbor)]
|
#[arg(short, long, default_value_t = DitherMethod::NearestNeighbor)]
|
||||||
dither_method: DitherMethod,
|
dither_method: DitherMethod,
|
||||||
|
#[arg(short, long, default_value_t = Palette::Default)]
|
||||||
|
palette: Palette,
|
||||||
input_file: PathBuf,
|
input_file: PathBuf,
|
||||||
output_file: PathBuf,
|
output_file: PathBuf,
|
||||||
}
|
}
|
||||||
|
@ -52,18 +54,6 @@ async fn main() -> anyhow::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let mut display: Box<dyn EInkPanel + Send> = match Wrapper::new() {
|
|
||||||
Ok(w) => {
|
|
||||||
info!("Found real hardware, using it");
|
|
||||||
Box::new(w)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
event!(Level::WARN, "Error opening display SPI interface: {e}");
|
|
||||||
warn!("Falling back to fake display");
|
|
||||||
Box::new(FakeEInk {})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Command::Convert(a) => {
|
Command::Convert(a) => {
|
||||||
let input = image::ImageReader::open(a.input_file)?
|
let input = image::ImageReader::open(a.input_file)?
|
||||||
|
@ -81,6 +71,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
result.into_rgbimage().save(a.output_file)?;
|
result.into_rgbimage().save(a.output_file)?;
|
||||||
}
|
}
|
||||||
Command::Show => {
|
Command::Show => {
|
||||||
|
let mut display = get_display();
|
||||||
let img: RgbImage = image::ImageReader::open("image.png")?.decode()?.into();
|
let img: RgbImage = image::ImageReader::open("image.png")?.decode()?.into();
|
||||||
error!("HI");
|
error!("HI");
|
||||||
|
|
||||||
|
@ -91,6 +82,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
display.display(&eink_buf)?;
|
display.display(&eink_buf)?;
|
||||||
}
|
}
|
||||||
Command::Serve => {
|
Command::Serve => {
|
||||||
|
let display = get_display();
|
||||||
let ctx = api::AppState::new(display);
|
let ctx = api::AppState::new(display);
|
||||||
|
|
||||||
let app = api::router().with_state(ctx);
|
let app = api::router().with_state(ctx);
|
||||||
|
|
Loading…
Reference in a new issue