Implement fading
This commit is contained in:
parent
bfb3b23d70
commit
581e4263fc
@ -1,28 +1,34 @@
|
||||
use crate::dimensions::{calculate_resize_dimensions, Dimensions};
|
||||
use image::ImageReader;
|
||||
use macroquad::texture::Texture2D;
|
||||
use macroquad::texture::{Image, Texture2D};
|
||||
use std::path::{Path, PathBuf};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub struct ImageProvider<'a> {
|
||||
path: &'a Path,
|
||||
directory_it: Box<dyn Iterator<Item = Result<walkdir::DirEntry, walkdir::Error>>>,
|
||||
image: Option<Image>,
|
||||
texture: Option<Texture2D>,
|
||||
texture_darkening_factor: f32,
|
||||
screen_dimension: Dimensions,
|
||||
}
|
||||
|
||||
impl<'a> ImageProvider<'a> {
|
||||
pub fn new(screen_dimension: Dimensions, path: &'a Path) -> Self {
|
||||
Self {
|
||||
directory_it: Box::new(WalkDir::new(&path).max_open(8).into_iter()),
|
||||
directory_it: Box::new(WalkDir::new(path).max_open(8).into_iter()),
|
||||
image: None,
|
||||
texture: None,
|
||||
screen_dimension,
|
||||
path,
|
||||
texture_darkening_factor: 1.0f32,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_next_image(&mut self) -> anyhow::Result<()> {
|
||||
let path = self.get_next_image_path()?;
|
||||
println!("Loading image: {path:?}");
|
||||
let now = chrono::Local::now().time();
|
||||
let image = ImageReader::open(path)?.decode()?;
|
||||
|
||||
let image_dim = Dimensions::new(image.width(), image.height());
|
||||
@ -34,19 +40,51 @@ impl<'a> ImageProvider<'a> {
|
||||
image::imageops::FilterType::Lanczos3,
|
||||
);
|
||||
|
||||
self.texture = Some(Texture2D::from_rgba8(
|
||||
image.width().try_into()?,
|
||||
image.height().try_into()?,
|
||||
&image.into_rgba8(),
|
||||
));
|
||||
let mut i = Image::empty();
|
||||
i.width = image.width() as u16;
|
||||
i.height = image.height() as u16;
|
||||
i.bytes = image.into_rgba8().into_raw();
|
||||
|
||||
self.image = Some(i);
|
||||
self.texture = None;
|
||||
|
||||
let elapsed = chrono::Local::now().time() - now;
|
||||
println!(
|
||||
"Loading image elapsed time: {}ms",
|
||||
elapsed.num_milliseconds()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_current_texture(&self) -> anyhow::Result<&Texture2D> {
|
||||
self.texture
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow::anyhow!("No image loaded"))
|
||||
pub fn get_current_texture(&mut self, darkening_factor: f32) -> anyhow::Result<&Texture2D> {
|
||||
if (darkening_factor - self.texture_darkening_factor).abs() > f32::EPSILON {
|
||||
self.texture_darkening_factor = darkening_factor;
|
||||
self.texture = None;
|
||||
}
|
||||
|
||||
if self.texture.is_none() {
|
||||
let darken_image = self
|
||||
.image
|
||||
.as_ref()
|
||||
.map(|i| {
|
||||
let mut darken_image = i.clone();
|
||||
darken_image.bytes.iter_mut().for_each(|b| {
|
||||
*b = (f32::from(*b) * darkening_factor) as u8;
|
||||
});
|
||||
darken_image
|
||||
})
|
||||
.ok_or_else(|| anyhow::anyhow!("No image loaded"))?;
|
||||
|
||||
let text =
|
||||
Texture2D::from_rgba8(darken_image.width, darken_image.height, &darken_image.bytes);
|
||||
self.texture = Some(text);
|
||||
}
|
||||
|
||||
match self.texture {
|
||||
Some(ref texture) => Ok(texture),
|
||||
None => Err(anyhow::anyhow!("No texture available")),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_next_image_path(&mut self) -> anyhow::Result<PathBuf> {
|
||||
@ -65,7 +103,7 @@ impl<'a> ImageProvider<'a> {
|
||||
Some(Err(e)) => return Err(e.into()),
|
||||
None => {
|
||||
// Reset the iterator when we reach the end
|
||||
self.directory_it = Box::new(WalkDir::new(&self.path).max_open(8).into_iter());
|
||||
self.directory_it = Box::new(WalkDir::new(self.path).max_open(8).into_iter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
src/main.rs
38
src/main.rs
@ -31,11 +31,6 @@ fn display_image_centered(texture: &Texture2D) {
|
||||
);
|
||||
}
|
||||
|
||||
enum Mode {
|
||||
Black,
|
||||
Displayed,
|
||||
}
|
||||
|
||||
#[macroquad::main(window_conf)]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let settings = settings::Settings::new("settings.yml".into())?;
|
||||
@ -51,37 +46,38 @@ async fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
let now = chrono::Local::now().time();
|
||||
let start_fading = chrono::NaiveTime::from_hms_opt(22, 45, 0).unwrap();
|
||||
let go_to_bed = chrono::NaiveTime::from_hms_opt(23, 0, 0).unwrap();
|
||||
let wake_up = chrono::NaiveTime::from_hms_opt(9, 0, 0).unwrap();
|
||||
let full_brightness = chrono::NaiveTime::from_hms_opt(9, 15, 0).unwrap();
|
||||
|
||||
let mode = if now < go_to_bed && now > wake_up {
|
||||
Mode::Displayed
|
||||
let darkening_factor = if now < start_fading && now > full_brightness {
|
||||
1.0f32
|
||||
} else if now > start_fading && now < go_to_bed {
|
||||
(go_to_bed - now).num_seconds() as f32 / (go_to_bed - start_fading).num_seconds() as f32
|
||||
} else if now > wake_up && now < full_brightness {
|
||||
(now - wake_up).num_seconds() as f32 / (full_brightness - wake_up).num_seconds() as f32
|
||||
} else {
|
||||
Mode::Black
|
||||
0.0f32
|
||||
};
|
||||
|
||||
match mode {
|
||||
Mode::Black => {
|
||||
clear_background(BLACK);
|
||||
}
|
||||
Mode::Displayed => {
|
||||
display_frame(&provider)?;
|
||||
if time.elapsed() > settings.duration {
|
||||
provider.load_next_image()?;
|
||||
time = Instant::now();
|
||||
}
|
||||
display_frame(&mut provider, darkening_factor)?;
|
||||
if time.elapsed() > settings.duration {
|
||||
if darkening_factor > 0.0f32 {
|
||||
provider.load_next_image()?;
|
||||
}
|
||||
time = Instant::now();
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
thread::sleep(Duration::from_millis(400));
|
||||
next_frame().await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn display_frame(provider: &ImageProvider) -> anyhow::Result<()> {
|
||||
let image = provider.get_current_texture()?;
|
||||
fn display_frame(provider: &mut ImageProvider, darkening_factor: f32) -> anyhow::Result<()> {
|
||||
let image = provider.get_current_texture(darkening_factor)?;
|
||||
clear_background(BLACK);
|
||||
display_image_centered(image);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ impl Settings {
|
||||
.add_source(File::from(settings_file))
|
||||
.build()?;
|
||||
|
||||
let photo_path = settings.get_string("photo_path")?.try_into()?;
|
||||
let photo_path = settings.get_string("photo_path")?.into();
|
||||
let duration = settings.get_int("duration")?;
|
||||
|
||||
Ok(Self {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user