Add support for loading GIF files directly
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
|
use image::codecs::gif::GifDecoder;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::pix::canvas::Canvas;
|
use crate::pix::canvas::Canvas;
|
||||||
use image::imageops::FilterType;
|
use image::imageops::FilterType;
|
||||||
use image::DynamicImage;
|
use image::{AnimationDecoder, DynamicImage};
|
||||||
|
|
||||||
/// A manager that manages all images to print.
|
/// A manager that manages all images to print.
|
||||||
pub struct ImageManager {
|
pub struct ImageManager {
|
||||||
@@ -34,7 +36,7 @@ impl ImageManager {
|
|||||||
let image_manager = ImageManager::from(
|
let image_manager = ImageManager::from(
|
||||||
paths
|
paths
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|path| load_image(path, size))
|
.flat_map(|path| load_image(path, size))
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -86,7 +88,7 @@ impl ImageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Load the image at the given path, and size it correctly
|
/// Load the image at the given path, and size it correctly
|
||||||
fn load_image(path: &str, size: (u16, u16)) -> DynamicImage {
|
fn load_image(path: &str, size: (u16, u16)) -> Vec<DynamicImage> {
|
||||||
// Create a path instance
|
// Create a path instance
|
||||||
let path = Path::new(&path);
|
let path = Path::new(&path);
|
||||||
|
|
||||||
@@ -95,9 +97,30 @@ fn load_image(path: &str, size: (u16, u16)) -> DynamicImage {
|
|||||||
panic!("The given path does not exist or is not a file");
|
panic!("The given path does not exist or is not a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the image
|
let extension = path
|
||||||
let image = image::open(path).unwrap();
|
.extension()
|
||||||
|
.and_then(|e| e.to_str())
|
||||||
|
.map(|e| e.to_lowercase());
|
||||||
|
|
||||||
// Resize the image to fit the screen
|
// Load image(s)
|
||||||
image.resize_exact(size.0 as u32, size.1 as u32, FilterType::Gaussian)
|
let images = match extension.as_deref() {
|
||||||
|
// Load all GIF frames
|
||||||
|
Some("gif") => GifDecoder::new(File::open(path).unwrap())
|
||||||
|
.expect("failed to decode GIF file")
|
||||||
|
.into_frames()
|
||||||
|
.collect_frames()
|
||||||
|
.expect("failed to parse GIF frames")
|
||||||
|
.into_iter()
|
||||||
|
.map(|frame| DynamicImage::ImageRgba8(frame.into_buffer()))
|
||||||
|
.collect(),
|
||||||
|
|
||||||
|
// Load single image
|
||||||
|
_ => vec![image::open(path).unwrap()],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resize images to fit the screen
|
||||||
|
images
|
||||||
|
.into_iter()
|
||||||
|
.map(|image| image.resize_exact(size.0 as u32, size.1 as u32, FilterType::Gaussian))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user