Rust图像优化库oxipng的使用:高效无损PNG压缩与处理工具
Rust图像优化库oxipng的使用:高效无损PNG压缩与处理工具
概述
Oxipng是一个多线程无损PNG/APNG压缩优化器。它可以通过命令行界面使用,也可以作为库在其他Rust程序中使用。
安装
对于Windows用户,可以从GitHub发布页面下载Oxipng。对于MacOS或Linux用户,建议从发行版的软件包仓库安装。
也可以通过Cargo安装:
cargo install oxipng
或者从源码构建:
git clone https://github.com/shssoichiro/oxipng.git
cd oxipng
cargo build --release
cp target/release/oxipng /usr/local/bin
当前最低支持的Rust版本是1.74.0。
使用
Oxipng是一个命令行工具。一个适合网页使用的示例:
oxipng -o 4 --strip safe --alpha *.png
常用选项:
- 优化级别:
-o 0
到-o 6
(或-o max
),数字越小速度越快,数字越大压缩越好 - 剥离:
--strip [safe,all]
用于从处理后的图像中删除元数据信息 - Alpha:
--alpha
可以通过改变完全透明像素的颜色值来改进带透明度图像的压缩
Git集成
通过pre-commit集成,创建.pre-commit-config.yaml
文件:
repos:
- repo: https://github.com/shssoichiro/oxipng
rev: v9.1.4
hooks:
- id: oxipng
args: ["-o", "4", "--strip", "safe", "--alpha"]
Docker使用
Docker镜像可用于linux/amd64和linux/arm64:
docker run --rm -v $(pwd):/work ghcr.io/shssoichiro/oxipng -o 4 /work/file.png
库使用
Oxipng也可以作为库在其他Rust项目中使用。在Cargo.toml中添加依赖:
oxipng = { version = "9.0", features = ["parallel", "zopfli", "filetime"], default-features = false }
完整示例代码
use oxipng::{optimize, Options};
fn main() {
// 设置优化选项
let mut options = Options::from_preset(4); // 使用预设级别4
// 配置其他选项
options.strip = oxipng::StripChunks::Safe; // 安全移除元数据
options.alpha = true; // 优化透明像素
// 优化PNG文件
let input_path = "input.png";
let output_path = "output.png";
match optimize(&input_path, &output_path, &options) {
Ok(_) => println!("优化成功!"),
Err(e) => eprintln!("优化失败: {}", e),
}
}
性能基准
测试显示Oxipng 9.0.0比OptiPNG 0.7.7快2.22到5.01倍。
许可证
Oxipng是开源软件,采用MIT许可证。
贡献
欢迎通过GitHub提交pull request贡献代码,或通过GitHub issues报告问题。
完整示例demo
以下是一个更完整的示例,展示了如何批量处理PNG文件并处理错误:
use oxipng::{optimize, Options};
use std::path::Path;
use std::fs;
fn optimize_png(input_path: &str, output_path: &str) -> Result<(), String> {
// 设置优化选项
let mut options = Options::from_preset(4); // 使用预设级别4
// 配置其他选项
options.strip = oxipng::StripChunks::Safe; // 安全移除元数据
options.alpha = true; // 优化透明像素
// 优化PNG文件
optimize(&Path::new(input_path), &Path::new(output_path), &options)
.map_err(|e| format!("优化失败: {}", e))
}
fn main() {
// 获取当前目录下所有PNG文件
let png_files = fs::read_dir(".")
.unwrap()
.filter_map(|entry| {
let entry = entry.unwrap();
let path = entry.path();
if path.extension().map_or(false, |ext| ext == "png") {
Some(path.to_str().unwrap().to_string())
} else {
None
}
});
// 批量优化PNG文件
for input_path in png_files {
let output_path = format!("optimized_{}", input_path);
match optimize_png(&input_path, &output_path) {
Ok(_) => println!("优化成功: {} -> {}", input_path, output_path),
Err(e) => eprintln!("{}: {}", input_path, e),
}
}
}
这个示例扩展了基本功能,包含以下改进:
- 批量处理当前目录下所有PNG文件
- 为优化后的文件添加"optimized_"前缀
- 更详细的错误处理和日志输出
- 使用Path类型处理文件路径
- 将优化逻辑封装为单独函数
Rust图像优化库oxipng的使用:高效无损PNG压缩与处理工具
介绍
oxipng是一个用Rust编写的高性能PNG优化器,它可以显著减小PNG文件大小而不损失图像质量。作为pngquant和optipng的替代品,oxipng提供了更好的压缩比和更快的处理速度。
主要特性:
- 完全无损的PNG优化
- 多线程处理,速度极快
- 支持多种压缩级别
- 自动选择最佳PNG色彩模式
- 保留所有重要的PNG元数据
- 跨平台支持
安装方法
作为命令行工具安装
cargo install oxipng
作为库添加到项目
在Cargo.toml中添加依赖:
[dependencies]
oxipng = "8.0"
基本使用方法
命令行使用
# 基本压缩
oxipng input.png
# 指定输出文件
oxipng input.png -o output.png
# 使用最高压缩级别(较慢但效果更好)
oxipng input.png --opt max
# 递归处理目录下所有PNG文件
oxipng -r ./images
在Rust代码中使用
use oxipng::{optimize, Options};
fn main() {
let options = Options {
opt_level: 2, // 压缩级别 0-6
strip: oxipng::StripChunks::Safe, // 移除非关键元数据
..Options::default()
};
let input = "input.png";
let output = "output.png";
// 优化PNG文件
if let Err(e) = optimize(&input.into(), &output.into(), &options) {
eprintln!("优化失败: {}", e);
}
}
高级功能示例
批量处理并保留原始文件
use oxipng::{optimize, Options};
use std::path::Path;
use walkdir::WalkDir;
fn optimize_directory(dir: &str) {
let options = Options::from_preset(4); // 使用预设级别4
for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) {
if entry.path().extension().map_or(false, |ext| ext == "png") {
let in_path = entry.path();
let out_path = in_path.with_extension("optimized.png");
if let Err(e) = optimize(in_path, &out_path, &options) {
eprintln!("处理 {} 失败: {}", in_path.display(), e);
}
}
}
}
自定义压缩选项
use oxipng::{optimize, Options, Deflate, StripChunks};
let options = Options {
opt_level: 5,
filter: oxipng::FilterType::Aggressive,
interlaced: Some(false), // 强制不使用隔行扫描
preserve_attrs: true, // 保留文件属性
backup: false, // 不创建备份文件
fix_errors: true, // 自动修复错误
strip: StripChunks::All, // 移除所有元数据
deflate: Deflate {
compression: 9, // 最高压缩级别
..Default::default()
},
..Options::default()
};
完整示例demo
下面是一个完整的示例,展示如何使用oxipng库批量优化一个目录中的所有PNG文件:
use oxipng::{optimize, Options, StripChunks};
use std::path::Path;
use walkdir::WalkDir;
use std::fs;
fn main() {
// 设置输入和输出目录
let input_dir = "./input_images";
let output_dir = "./optimized_images";
// 创建输出目录
fs::create_dir_all(output_dir).expect("无法创建输出目录");
// 配置优化选项
let options = Options {
opt_level: 4, // 中等优化级别
strip: StripChunks::Safe, // 移除非关键元数据
backup: false, // 不创建备份
fix_errors: true, // 自动修复错误
..Options::default()
};
// 遍历输入目录
for entry in WalkDir::new(input_dir).into_iter().filter_map(|e| e.ok()) {
if entry.path().extension().map_or(false, |ext| ext == "png") {
let in_path = entry.path();
let out_path = Path::new(output_dir).join(in_path.file_name().unwrap());
println!("正在优化: {}", in_path.display());
match optimize(in_path, &out_path, &options) {
Ok(_) => println!("优化成功: {}", out_path.display()),
Err(e) => eprintln!("优化失败: {} - {}", in_path.display(), e),
}
}
}
println!("批量优化完成!");
}
性能对比
oxipng通常比其他PNG优化工具快2-5倍,同时能提供更好的压缩率。在8核CPU上处理大型PNG集合时,速度优势尤为明显。
注意事项
- oxipng是无损优化工具,不会改变图像视觉效果
- 最高优化级别(6)可能非常耗时,适合最终发布版本
- 某些PNG文件可能已经高度优化,压缩空间有限
- 建议在CI/CD流程中集成oxipng来自动优化资源
oxipng是Rust生态中处理PNG图像的优秀选择,特别适合需要高性能批量处理的场景。