image库中有许多对图片处理方法.
可以参考一份中文翻译(https://www.jianshu.com/p/342c6a4bc7a1).
也可以去仓库地址中查看(https://github.com/image-rs/image),仓库中examples文件夹中放着一些例子,其中就有图片压缩的例子,提供了几种压缩算法的对比,下面的例子是改动了官方的例子,对文件夹中的图片文件进行压缩:
Cargo.toml设置,主要是依赖image库。
[package]
name = "image-compress-tools"
version = "0.1.0"
authors = [""]
edition = "2018"
[dependencies]
image = "0.22.3"
use image::{FilterType, JPEG, PNG};
use std::fmt;
use std::fs::{self, File};
use std::time::{Duration, Instant};
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),
}
}
}
fn main() {
let exts: Vec<&str> = vec!["png", "jpg", "jpeg"];
use std::path::Path;
//以当前目录为源目录,以当前目录+scale目录
let src_path = Path::new(".");
let target_path = src_path.join("scale");
let target_path = target_path.as_path();
fs::create_dir_all(target_path).unwrap();
for entry in src_path.read_dir().expect("read_dir call failed") {
if let Ok(entry) = entry {
let path = entry.path();
let img_path = &path.as_path();
if img_path.is_file() {
let extension = match img_path.extension() {
Some(ext) => ext.to_str().unwrap(),
_ => break,
};
if exts.contains(&extension) {//文件后缀判断
let file_name = img_path.file_name().unwrap().to_str().unwrap();
let timer = Instant::now();
println!("target by {} in {}", file_name, Elapsed::from(&timer));
let tiny = match image::open(img_path) {
Ok(image) => image,
_ => {
println!(
"{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
file_name
);
break;
}
};
let tiny = match image::open(img_path) {
Ok(image) => image,
_ => {
println!(
"{} 压缩失败,图片格式有误,可以使用画图工具打开重新保存",
file_name
);
break;
}
};
let scaled = tiny.resize(800, 600, FilterType::Triangle);//使用这个算法进行压缩
let mut output = File::create(target_path.join(file_name).as_path()).unwrap();
scaled.write_to(&mut output, JPEG).unwrap();//都输出成jpg格式
}
}
}
}
}
image图片格式支持:
目前该库基本支持市面上大部分的图片格式
- PNG (encode & decode)
- JPEG (encode & decode)
- GIF (encode & decode)
- BMP (encode & decode)
- ICO (encode & decode)
- TIFF (just decode)
- webp (just decode)
- PPM (encode & decode)
image::open方法通过打开文件后,对文件名的后缀进行判断后调用对应的图片格式进行处理(这里就一个坑,一个真实是png的图片,文件后缀名是jpg,在打开时就会调用jpg相关处理方法,jpg会判断soi marker,却发现这个文件没有就会报错)。
官方的例子使用了几种压缩算法进行大小和效率对比,上面的例子使用了FilterType::Triangle。
("near", FilterType::Nearest),
("tri", FilterType::Triangle),
("xcmr", FilterType::CatmullRom),
("ygauss", FilterType::Gaussian),
("zlcz2", FilterType::Lanczos3),