[![rayon-badge]][rayon] [![glob-badge]][glob] [![image-badge]][image] [![cat-concurrency-badge]][cat-concurrency] [![cat-filesystem-badge]][cat-filesystem]
此示例:帮当前目录中的所有.jpg
文件生成缩略图,然后将其保存在名为thumbnails
的新文件夹中。
glob::glob_with
在当前目录中,查找 jpeg 文件。rayon
使用par_iter
,并发调整图像大小,每次都调用DynamicImage::resize
。
# #[macro_use]
# extern crate error_chain;
extern crate glob;
extern crate image;
extern crate rayon;
use std::path::Path;
use std::fs::create_dir_all;
# use error_chain::ChainedError;
use glob::{glob_with, MatchOptions};
use image::{FilterType, ImageError};
use rayon::prelude::*;
# error_chain! {
# foreign_links {
# Image(ImageError);
# Io(std::io::Error);
# Glob(glob::PatternError);
# }
# }
fn run() -> Result<()> {
let options: MatchOptions = Default::default();
let files: Vec<_> = glob_with("*.jpg", &options)?
.filter_map(|x| x.ok())
.collect();
if files.len() == 0 {
bail!("No .jpg files found in current directory");
}
let thumb_dir = "thumbnails";
create_dir_all(thumb_dir)?;
println!("Saving {} thumbnails into '{}'...", files.len(), thumb_dir);
let image_failures: Vec<_> = files
.par_iter()
.map(|path| {
make_thumbnail(path, thumb_dir, 300)
.map_err(|e| e.chain_err(|| path.display().to_string()))
})
.filter_map(|x| x.err())
.collect();
image_failures.iter().for_each(|x| println!("{}", x.display_chain()));
println!("{} thumbnails saved successfully", files.len() - image_failures.len());
Ok(())
}
fn make_thumbnail<PA, PB>(original: PA, thumb_dir: PB, longest_edge: u32) -> Result<()>
where
PA: AsRef<Path>,
PB: AsRef<Path>,
{
let img = image::open(original.as_ref())?;
let file_path = thumb_dir.as_ref().join(original);
Ok(img.resize(longest_edge, longest_edge, FilterType::Nearest)
.save(file_path)?)
}
#
# quick_main!(run);