feat: add image provider module

This commit is contained in:
Jean-Loup Beaussart 2024-11-14 22:59:06 +01:00
parent 08af03380c
commit f0ba4e47d9
No known key found for this signature in database
GPG Key ID: 582B3C35EAFE46F8

73
src/image_provider.rs Normal file
View File

@ -0,0 +1,73 @@
use crate::dimensions::{calculate_resize_dimensions, Dimensions};
use image::ImageReader;
use macroquad::texture::Texture2D;
use std::path::PathBuf;
use walkdir::WalkDir;
pub struct ImageProvider {
path: PathBuf,
directory_it: Box<dyn Iterator<Item = Result<walkdir::DirEntry, walkdir::Error>>>,
texture: Option<Texture2D>,
screen_dimension: Dimensions,
}
impl ImageProvider {
pub fn new(screen_dimension: Dimensions, path: PathBuf) -> Self {
Self {
directory_it: Box::new(WalkDir::new(&path).max_open(8).into_iter()),
texture: None,
screen_dimension,
path,
}
}
pub fn load_next_image(&mut self) -> anyhow::Result<()> {
let path = self.get_next_image_path()?;
let image = ImageReader::open(path)?.decode()?;
let image_dim = Dimensions::new(image.width(), image.height());
let new_dim = calculate_resize_dimensions(self.screen_dimension, image_dim);
let image = image.resize(
new_dim.width,
new_dim.height,
image::imageops::FilterType::Lanczos3,
);
self.texture = Some(Texture2D::from_rgba8(
image.width().try_into()?,
image.height().try_into()?,
&image.into_rgba8(),
));
Ok(())
}
pub fn get_current_texture(&self) -> anyhow::Result<&Texture2D> {
self.texture
.as_ref()
.ok_or_else(|| anyhow::anyhow!("No image loaded"))
}
fn get_next_image_path(&mut self) -> anyhow::Result<PathBuf> {
loop {
match self.directory_it.next() {
Some(Ok(entry)) => {
if entry.file_type().is_file()
&& entry
.path()
.extension()
.is_some_and(|ext| ext == "jpg" || ext == "jpeg" || ext == "png")
{
return Ok(entry.path().to_path_buf());
}
}
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());
}
}
}
}
}