1use std::{env, fmt};
2use std::fs::{self, File};
3use std::path::Path;
4use std::time::{Duration, Instant};
5
6use image::imageops::FilterType;
7use image::ImageOutputFormat::{Jpeg, Png};
8
9struct Elapsed(Duration);
10
11impl Elapsed {
12 fn from(start: &Instant) -> Self {
13 Elapsed(start.elapsed())
14 }
15}
16
17impl fmt::Display for Elapsed {
18 fn fmt(&self, out: &mut fmt::Formatter) -> Result<(), fmt::Error> {
19 match (self.0.as_secs(), self.0.subsec_nanos()) {
20 (0, n) if n < 1000 => write!(out, "{} ns", n),
21 (0, n) if n < 1000_000 => write!(out, "{} µs", n / 1000),
22 (0, n) => write!(out, "{} ms", n / 1000_000),
23 (s, n) if s < 10 => write!(out, "{}.{:02} s", s, n / 10_000_000),
24 (s, _) => write!(out, "{} s", s),
25 }
26 }
27}
28
29pub fn dir_compression(in_dir: &Path, out_dir: &Path) {
30 for entry in in_dir.read_dir().expect("read_dir call failed") {
31 file_compression(entry.unwrap().path().as_path(), out_dir);
32 }
33}
34
35pub fn file_compression(in_file: &Path, out_dir: &Path) {
36 let extends: Vec<&str> = vec!["png", "jpg", "jpeg"];
37 if in_file.is_file() {
38 let extension = match in_file.extension() {
39 Some(ext) => ext.to_str().unwrap(),
40 _ => return,
41 };
42 if extends.contains(&extension) {let file_name = in_file.file_name().unwrap().to_str().unwrap();
44 let timer = Instant::now();
45 println!("target by {} in {}", file_name, Elapsed::from(&timer));
46 let tiny = match image::open(in_file) {
47 Ok(image) => image,
48 _ => {
49 println!(
50 "{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
51 file_name
52 );
53 return;
54 }
55 };
56 let tiny = match image::open(in_file) {
57 Ok(image) => image,
58 _ => {
59 println!(
60 "{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
61 file_name
62 );
63 return;
64 }
65 };
66 let scaled = tiny.resize(800, 600, FilterType::Triangle);let mut output = File::create(out_dir.join(file_name).as_path()).unwrap();
68 scaled.write_to(&mut output, Png).unwrap();}
70 }
71}