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),
        }
    }
}

这个示例扩展了基本功能,包含以下改进:

  1. 批量处理当前目录下所有PNG文件
  2. 为优化后的文件添加"optimized_"前缀
  3. 更详细的错误处理和日志输出
  4. 使用Path类型处理文件路径
  5. 将优化逻辑封装为单独函数

1 回复

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集合时,速度优势尤为明显。

注意事项

  1. oxipng是无损优化工具,不会改变图像视觉效果
  2. 最高优化级别(6)可能非常耗时,适合最终发布版本
  3. 某些PNG文件可能已经高度优化,压缩空间有限
  4. 建议在CI/CD流程中集成oxipng来自动优化资源

oxipng是Rust生态中处理PNG图像的优秀选择,特别适合需要高性能批量处理的场景。

回到顶部