1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::{env, fmt};
use std::fs::{self, File};
use std::path::Path;
use std::time::{Duration, Instant};

use image::imageops::FilterType;
use image::ImageOutputFormat::{Jpeg, Png};

struct Elapsed(Duration);

impl Elapsed {
    fn from(start: &Instant) -> Self {
        Elapsed(start.elapsed())
    }
}

impl fmt::Display for Elapsed {
    fn fmt(&self, out: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match (self.0.as_secs(), self.0.subsec_nanos()) {
            (0, n) if n < 1000 => write!(out, "{} ns", n),
            (0, n) if n < 1000_000 => write!(out, "{} µs", n / 1000),
            (0, n) => write!(out, "{} ms", n / 1000_000),
            (s, n) if s < 10 => write!(out, "{}.{:02} s", s, n / 10_000_000),
            (s, _) => write!(out, "{} s", s),
        }
    }
}

pub fn dir_compression(in_dir: &Path, out_dir: &Path) {
    for entry in in_dir.read_dir().expect("read_dir call failed") {
        file_compression(entry.unwrap().path().as_path(), out_dir);
    }
}

pub fn file_compression(in_file: &Path, out_dir: &Path) {
    let extends: Vec<&str> = vec!["png", "jpg", "jpeg"];
    if in_file.is_file() {
        let extension = match in_file.extension() {
            Some(ext) => ext.to_str().unwrap(),
            _ => return,
        };
        if extends.contains(&extension) {//文件后缀判断
            let file_name = in_file.file_name().unwrap().to_str().unwrap();
            let timer = Instant::now();
            println!("target by {} in {}", file_name, Elapsed::from(&timer));
            let tiny = match image::open(in_file) {
                Ok(image) => image,
                _ => {
                    println!(
                        "{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
                        file_name
                    );
                    return;
                }
            };
            let tiny = match image::open(in_file) {
                Ok(image) => image,
                _ => {
                    println!(
                        "{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
                        file_name
                    );
                    return;
                }
            };
            let scaled = tiny.resize(800, 600, FilterType::Triangle);//使用这个算法进行压缩
            let mut output = File::create(out_dir.join(file_name).as_path()).unwrap();
            scaled.write_to(&mut output, Png).unwrap();//都输出成jpg格式
        }
    }
}