Rust图像处理库jxl-modular的使用:高效模块化JPEG XL编解码与图像格式转换
Rust图像处理库jxl-modular的使用:高效模块化JPEG XL编解码与图像格式转换
jxl-modular介绍
jxl-modular是一个JPEG XL Modular图像解码器库。Modular图像表示一组网格(二维数组)的整数值。Modular图像主要用于无损图像,但有损VarDCT图像也使用它们来存储各种信息,如量化LF图像和varblock配置。
安装
在项目目录中运行以下Cargo命令:
cargo add jxl-modular
或者在Cargo.toml中添加以下行:
jxl-modular = "0.11.2"
使用示例
以下是使用jxl-modular进行JPEG XL图像解码的基本示例:
use jxl_modular::Modular;
use std::fs::File;
use std::io::Read;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 读取JPEG XL文件
let mut file = File::open("example.jxl")?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
// 创建Modular解码器
let modular = Modular::new();
// 解码图像
let result = modular.decode(&buffer)?;
// 处理解码后的图像数据
for channel in result.channels {
println!("Channel dimensions: {}x{}", channel.width, channel.height);
// 这里可以访问channel.data获取像素数据
}
Ok(())
}
高级用法
以下是一个更完整的示例,展示了如何将JPEG XL图像转换为PNG格式:
use jxl_modular::Modular;
use image::{ImageBuffer, RgbImage};
use std::fs::File;
use std::io::Read;
fn convert_jxl_to_png(input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 读取输入文件
let mut file = File::open(input_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
// 解码JPEG XL图像
let modular = Modular::new();
let decoded = modular.decode(&buffer)?;
// 假设我们有一个RGB图像(3个通道)
if decoded.channels.len() < 3 {
return Err("Not enough color channels".into());
}
let width = decoded.channels[0].width;
let height = decoded.channels[0].height;
// 创建图像缓冲区
let mut img: RgbImage = ImageBuffer::new(width as u32, height as u32);
// 填充像素数据
for y in 0..height {
for x in 0..width {
let r = decoded.channels[0].data[y * width + x];
let g = decoded.channels[1].data[y * width + x];
let b = decoded.channels[2].data[y * width + x];
img.put_pixel(x as u32, y as u32, image::Rgb([r as u8, g as u8, b as u8]));
}
}
// 保存为PNG
img.save(output_path)?;
Ok(())
}
fn main() {
if let Err(e) = convert_jxl_to_png("input.jxl", "output.png") {
eprintln!("Error: {}", e);
}
}
完整示例代码
以下是一个完整的示例,展示了如何从JPEG XL解码图像并转换为多种格式:
use jxl_modular::Modular;
use image::{ImageBuffer, RgbImage, ImageFormat};
use std::fs::File;
use std::io::Read;
use std::path::Path;
fn convert_jxl_image(
input_path: &str,
output_path: &str,
format: ImageFormat
) -> Result<(), Box<dyn std::error::Error>> {
// 读取输入文件
let mut file = File::open(input_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
// 解码JPEG XL图像
let modular = Modular::new();
let decoded = modular.decode(&buffer)?;
// 检查通道数量
if decoded.channels.len() < 3 {
return Err("需要至少3个颜色通道".into());
}
let width = decoded.channels[0].width;
let height = decoded.channels[0].height;
// 创建RGB图像缓冲区
let mut img: RgbImage = ImageBuffer::new(width as u32, height as u32);
// 填充像素数据
for y in 0..height {
for x in 0..width {
let r = decoded.channels[0].data[y * width + x];
let g = decoded.channels[1].data[y * width + x];
let b = decoded.channels[2].data[y * width + x];
img.put_pixel(x as u32, y as u32, image::Rgb([r as u8, g as u8, b as u8]));
}
}
// 根据指定格式保存图像
let output_file = File::create(output_path)?;
match format {
ImageFormat::Png => img.save_with_format(output_path, ImageFormat::Png)?,
ImageFormat::Jpeg => img.save_with_format(output_path, ImageFormat::Jpeg)?,
ImageFormat::Bmp => img.save_with_format(output_path, ImageFormat::Bmp)?,
_ => return Err("不支持的输出格式".into()),
}
Ok(())
}
fn main() {
// 转换为PNG
if let Err(e) = convert_jxl_image("input.jxl", "output.png", ImageFormat::Png) {
eprintln!("PNG转换错误: {}", e);
}
// 转换为JPEG
if let Err(e) = convert_jxl_image("input.jxl", "output.jpg", ImageFormat::Jpeg) {
eprintln!("JPEG转换错误: {}", e);
}
// 转换为BMP
if let Err(e) = convert_jxl_image("input.jxl", "output.bmp", ImageFormat::Bmp) {
eprintln!("BMP转换错误: {}", e);
}
}
特性
- 支持JPEG XL Modular图像解码
- 高效处理无损图像
- 支持多通道图像数据
- 可与其他图像处理库(如image-rs)集成
许可证
jxl-modular采用MIT或Apache-2.0双重许可。
1 回复
Rust图像处理库jxl-modular的使用:高效模块化JPEG XL编解码与图像格式转换
完整示例代码
下面是一个完整的示例程序,展示了jxl-modular库的主要功能:
use jxl_modular::{
decode::JxlDecoder,
encode::{JxlEncoder, JxlEncodingOptions},
metadata::JxlMetadata,
transcode::ImageTranscoder
};
use image::open;
use std::{
fs::File,
path::Path,
time::Instant
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例文件路径
let input_jxl = "input.jxl";
let input_png = "input.png";
let output_jxl = "output.jxl";
let output_png = "output.png";
let converted_jxl = "converted.jxl";
// 1. 解码JPEG XL图像
let start = Instant::now();
decode_jxl(input_jxl, output_png)?;
println!("解码完成,耗时: {:?}", start.elapsed());
// 2. 编码为JPEG XL
let start = Instant::now();
encode_to_jxl(input_png, output_jxl)?;
println!("编码完成,耗时: {:?}", start.elapsed());
// 3. 图像格式转换
let start = Instant::now();
convert_image(input_png, converted_jxl)?;
println!("格式转换完成,耗时: {:?}", start.elapsed());
// 4. 自定义编码参数
let start = Instant::now();
custom_encode(input_png, "custom_encoded.jxl")?;
println!("自定义编码完成,耗时: {:?}", start.elapsed());
// 5. 读取元数据
read_metadata(input_jxl)?;
Ok(())
}
/// 解码JPEG XL图像
fn decode_jxl(input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 打开输入文件
let mut file = File::open(input_path)?;
// 创建解码器
let mut decoder = JxlDecoder::new(&mut file)?;
// 解码图像
let image = decoder.decode()?;
// 保存为PNG格式
image.save(output_path)?;
Ok(())
}
/// 编码为JPEG XL
fn encode_to_jxl(input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 使用image库打开图像
let img = open(input_path)?;
// 创建编码器
let mut encoder = JxlEncoder::new(img)?;
// 创建输出文件
let mut output_file = File::create(output_path)?;
// 编码并写入文件
encoder.encode_to(&mut output_file)?;
Ok(())
}
/// 图像格式转换
fn convert_image(input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 创建转码器
let transcoder = ImageTranscoder::new(Path::new(input_path))?;
// 转码为目标格式
transcoder.transcode_to(Path::new(output_path))?;
Ok(())
}
/// 自定义编码参数
fn custom_encode(input_path: &str, output_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 使用image库打开图像
let img = open(input_path)?;
// 设置编码选项
let options = JxlEncodingOptions {
quality: 90, // 质量设置 (0-100)
effort: 7, // 编码努力程度 (1-9)
lossless: false, // 非无损编码
..Default::default()
};
// 使用自定义选项创建编码器
let mut encoder = JxlEncoder::with_options(img, options)?;
// 创建输出文件
let mut output_file = File::create(output_path)?;
// 编码并写入文件
encoder.encode_to(&mut output_file)?;
Ok(())
}
/// 读取图像元数据
fn read_metadata(input_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 打开输入文件
let mut file = File::open(input_path)?;
// 读取元数据
let metadata = JxlMetadata::read_from(&mut file)?;
// 打印元数据信息
println!("图像元数据:");
println!("宽度: {}", metadata.width);
println!("高度: {}", metadata.height);
println!("色彩空间: {:?}", metadata.color_space);
println!("包含的元数据块数量: {}", metadata.metadata_chunks.len());
Ok(())
}
示例说明
这个完整示例展示了jxl-modular库的五个主要功能:
- 解码JPEG XL图像:将JPEG XL格式文件解码并保存为PNG格式
- 编码为JPEG XL:将普通图像格式(如PNG)编码为JPEG XL格式
- 图像格式转换:自动识别输入格式并转换为JPEG XL格式
- 自定义编码参数:使用自定义质量、压缩级别等参数进行编码
- 读取元数据:从JPEG XL文件中提取并显示元数据信息
每个操作都添加了计时功能,方便评估性能。要运行此示例,需要准备以下测试文件:
- input.jxl (JPEG XL格式图像)
- input.png (PNG格式图像)
性能优化建议
- 对于批量处理,可以重用编码器/解码器实例
- 大文件处理建议使用异步I/O
- 根据需求调整编码参数平衡速度和质量
依赖说明
运行此示例需要在Cargo.toml中添加以下依赖:
[dependencies]
jxl-modular = "0.3"
image = "0.24"
这个示例涵盖了jxl-modular库的主要功能,可以作为您项目开发的起点。