feat: add image provider module
This commit is contained in:
parent
08af03380c
commit
f0ba4e47d9
73
src/image_provider.rs
Normal file
73
src/image_provider.rs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user