Rust色彩处理库jxl-color的使用:高性能JPEG XL图像格式色彩空间转换与处理
Rust色彩处理库jxl-color的使用:高性能JPEG XL图像格式色彩空间转换与处理
此crate提供了一组与JPEG XL规范定义的颜色编码相关的函数。特别是,这些函数可以执行从XYB色彩空间到所有可以在JPEG XL图像头中信号化的"枚举色彩空间"的转换。
安装
在项目目录中运行以下Cargo命令:
cargo add jxl-color
或者在Cargo.toml中添加以下行:
jxl-color = "0.11.0"
使用示例
以下是一个使用jxl-color库进行色彩空间转换的完整示例:
use jxl_color::{icc, ColourEncoding, EnumColourEncoding, RenderingIntent, WhitePoint};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个RGB色彩编码配置
let rgb_encoding = ColourEncoding::Enum(EnumColourEncoding {
colour_space: jxl_color::ColourSpace::Rgb,
white_point: WhitePoint::D65,
primaries: jxl_color::Primaries::Srgb,
tf: jxl_color::TransferFunction::Srgb,
rendering_intent: RenderingIntent::Perceptual,
});
// 创建一个灰度色彩编码配置
let gray_encoding = ColourEncoding::Enum(EnumColourEncoding {
colour_space: jxl_color::ColourSpace::Grey,
white_point: WhitePoint::D65,
primaries: jxl_color::Primaries::Srgb,
tf: jxl_color::TransferFunction::Srgb,
rendering_intent: RenderingIntent::Perceptual,
});
// 示例:将像素数据从RGB转换为灰度
let rgb_pixels = vec![
[0.5f32, 0.3, 0.8], // R, G, B
[0.2, 0.9, 0.1],
[0.7, 0.4, 0.6],
];
let mut gray_pixels = Vec::new();
for rgb in &rgb_pixels {
// 在实际应用中,这里会使用jxl-color的色彩转换函数
// 简化示例:使用简单的亮度公式
let gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
gray_pixels.push(gray);
}
println!("转换后的灰度像素: {:?}", gray_pixels);
// 示例:处理ICC配置文件
if let Ok(icc_profile) = icc::write_icc(&rgb_encoding) {
println!("生成的ICC配置文件大小: {} 字节", icc_profile.len());
}
Ok(())
}
高级使用示例
use jxl_color::{ColourEncoding, EnumColourEncoding, WhitePoint, RenderingIntent};
fn create_custom_color_encoding() -> ColourEncoding {
// 创建自定义色彩编码配置
ColourEncoding::Enum(EnumColourEncoding {
colour_space: jxl_color::ColourSpace::Rgb,
white_point: WhitePoint::D65,
primaries: jxl_color::Primaries::AdobeRgb,
tf: jxl_color::TransferFunction::Gamma(2.2),
rendering_intent: RenderingIntent::Relative,
})
}
fn validate_color_encoding(encoding: &ColourEncoding) -> bool {
// 验证色彩编码配置的有效性
match encoding {
ColourEncoding::Enum(e) => {
// 检查色彩空间和参数是否兼容
matches!(
(e.colour_space, e.white_point, e.primaries),
(jxl_color::ColourSpace::Rgb, _, _) |
(jxl_color::ColourSpace::Grey, _, _)
)
}
ColourEncoding::Icc(_) => true, // ICC配置总是有效的
}
}
fn main() {
let custom_encoding = create_custom_color_encoding();
if validate_color_encoding(&custom_encoding) {
println!("色彩编码配置有效");
// 在实际应用中,这里会使用jxl-color的色彩转换功能
// 例如:xyb_to_linear_rgb, linear_rgb_to_xyb 等函数
} else {
println!("色彩编码配置无效");
}
}
完整示例代码
use jxl_color::{
icc,
ColourEncoding,
EnumColourEncoding,
RenderingIntent,
WhitePoint,
ColourSpace,
Primaries,
TransferFunction
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建标准sRGB色彩编码配置
let srgb_encoding = ColourEncoding::Enum(EnumColourEncoding {
colour_space: ColourSpace::Rgb,
white_point: WhitePoint::D65,
primaries: Primaries::Srgb,
tf: TransferFunction::Srgb,
rendering_intent: RenderingIntent::Perceptual,
});
// 创建Adobe RGB色彩编码配置
let adobe_rgb_encoding = ColourEncoding::Enum(EnumColourEncoding {
colour_space: ColourSpace::Rgb,
white_point: WhitePoint::D65,
primaries: Primaries::AdobeRgb,
tf: TransferFunction::Gamma(2.2),
rendering_intent: RenderingIntent::Relative,
});
// 创建灰度色彩编码配置
let gray_encoding = ColourEncoding::Enum(EnumColourEncoding {
colour_space: ColourSpace::Grey,
white_point: WhitePoint::D65,
primaries: Primaries::Srgb,
tf: TransferFunction::Srgb,
rendering_intent: RenderingIntent::Perceptual,
});
// 示例像素数据
let rgb_pixels = vec![
[0.5f32, 0.3, 0.8], // 紫色
[0.2, 0.9, 0.1], // 黄绿色
[0.7, 0.4, 0.6], // 粉紫色
[1.0, 1.0, 1.0], // 白色
[0.0, 0.0, 0.0], // 黑色
];
println!("原始RGB像素数据:");
for (i, pixel) in rgb_pixels.iter().enumerate() {
println!("像素 {}: R={:.2}, G={:.2}, B={:.2}", i, pixel[0], pixel[1], pixel[2]);
}
// 生成ICC配置文件
match icc::write_icc(&srgb_encoding) {
Ok(icc_profile) => {
println!("\n生成的sRGB ICC配置文件大小: {} 字节", icc_profile.len());
}
Err(e) => {
eprintln!("生成ICC配置文件失败: {}", e);
}
}
match icc::write_icc(&adobe_rgb_encoding) {
Ok(icc_profile) => {
println!("生成的Adobe RGB ICC配置文件大小: {} 字节", icc_profile.len());
}
Err(e) => {
eprintln!("生成ICC配置文件失败: {}", e);
}
}
// 验证色彩编码配置
println!("\n色彩编码配置验证:");
println!("sRGB配置有效: {}", validate_color_encoding(&srgb_encoding));
println!("Adobe RGB配置有效: {}", validate_color_encoding(&adobe_rgb_encoding));
println!("灰度配置有效: {}", validate_color_encoding(&gray_encoding));
Ok(())
}
fn validate_color_encoding(encoding: &ColourEncoding) -> bool {
// 验证色彩编码配置的有效性
match encoding {
ColourEncoding::Enum(e) => {
// 检查色彩空间和参数是否兼容
matches!(
(e.colour_space, e.white_point, e.primaries),
(ColourSpace::Rgb, _, _) |
(ColourSpace::Grey, _, _)
)
}
ColourEncoding::Icc(_) => true, // ICC配置总是有效的
}
}
// 自定义色彩转换函数示例
fn convert_rgb_to_grayscale(rgb_pixels: &[[f32; 3]]) -> Vec<f32> {
let mut gray_pixels = Vec::with_capacity(rgb_pixels.len());
for rgb in rgb_pixels {
// 使用标准的亮度转换公式
let gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
gray_pixels.push(gray);
}
gray_pixels
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_grayscale_conversion() {
let test_pixels = vec![[1.0f32, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]];
let result = convert_rgb_to_grayscale(&test_pixels);
// 验证转换结果
assert_eq!(result.len(), 3);
assert!((result[0] - 0.299).abs() < 0.001); // 红色
assert!((result[1] - 0.587).abs() < 0.001); // 绿色
assert!((result[2] - 0.114).abs() < 0.001); // 蓝色
}
}
1 回复
Rust色彩处理库jxl-color:高性能JPEG XL图像格式色彩空间转换与处理
概述
jxl-color是一个专为JPEG XL图像格式设计的Rust色彩处理库,提供高性能的色彩空间转换和色彩管理功能。该库支持多种色彩空间和色彩编码规范,能够高效处理JPEG XL格式中的ICC配置文件、色彩空间定义和色彩转换操作。
主要特性
- 完整的色彩空间支持(RGB、灰度、XYB等)
- ICC配置文件解析和处理
- 高性能的色彩转换运算
- 与JPEG XL编码规范完全兼容
- 无依赖的纯Rust实现
安装方法
在Cargo.toml中添加依赖:
[dependencies]
jxl-color = "0.3"
基本使用方法
1. 色彩空间转换
use jxl_color::{icc::IccProfile, ColorEncoding};
// 创建色彩编码配置
let src_encoding = ColorEncoding::srgb();
let dst_encoding = ColorEncoding::linear_srgb();
// 执行色彩空间转换
let converted_pixels = jxl_color::transform(
&src_encoding,
&dst_encoding,
pixel_data, // 原始像素数据
width,
height
).unwrap();
2. ICC配置文件处理
use jxl_color::icc::IccProfile;
// 从字节数据创建ICC配置文件
let icc_data: Vec<u8> = // 从文件或网络加载ICC数据
let profile = IccProfile::new(icc_data).unwrap();
// 转换为色彩编码
let color_encoding = profile.to_color_encoding().unwrap();
// 使用ICC配置文件进行色彩转换
let transformed = profile.transform_to(
&ColorEncoding::srgb(),
pixel_data,
width,
height
).unwrap();
3. 像素数据处理示例
use jxl_color::{ColorEncoding, PixelFormat};
fn process_image_pixels(pixels: &[u8], width: u32, height: u32) {
// 定义源和目标色彩空间
let src = ColorEncoding::srgb();
let dst = ColorEncoding::cmyk();
// 执行转换
let result = jxl_color::transform(
&src,
&dst,
pixels,
width,
height
).expect("色彩转换失败");
// 处理转换后的像素数据
process_converted_pixels(&result);
}
高级用法
自定义色彩空间
use jxl_color::{ColorEncoding, WhitePoint, Primaries};
// 创建自定义色彩空间
let custom_encoding = ColorEncoding::new(
Primaries::Bt709,
WhitePoint::D65,
jxl_color::TransferFunction::Gamma(2.2),
jxl_color::RenderingIntent::Perceptual
);
批量处理优化
use jxl_color::{ColorTransform, ColorEncoding};
// 预创建色彩转换器以提高性能
let transform = ColorTransform::new(
&ColorEncoding::srgb(),
&ColorEncoding::linear_srgb()
).unwrap();
// 批量处理多个图像
for image in images {
let converted = transform.transform(
image.pixels(),
image.width(),
image.height()
).unwrap();
// 处理转换后的图像
}
错误处理
use jxl_color::Error;
match jxl_color::transform(&src, &dst, pixels, width, height) {
Ok(result) => {
// 处理成功结果
}
Err(Error::UnsupportedColorSpace) => {
eprintln!("不支持的色彩空间");
}
Err(Error::InvalidIccProfile) => {
eprintln!("无效的ICC配置文件");
}
Err(e) => {
eprintln!("色彩转换错误: {}", e);
}
}
性能提示
- 尽可能重用ColorTransform实例
- 使用合适的像素格式(推荐使用f32格式以获得最佳精度)
- 批量处理图像数据以减少函数调用开销
- 在可能的情况下预计算色彩转换矩阵
这个库为处理JPEG XL图像提供了强大的色彩管理能力,特别适合需要高性能色彩处理的应用程序。
完整示例代码
use jxl_color::{ColorEncoding, ColorTransform, icc::IccProfile, Error};
use std::fs;
fn main() -> Result<(), Error> {
// 示例1: 基本色彩空间转换
println!("=== 基本色彩空间转换示例 ===");
// 创建测试像素数据 (sRGB格式的3x3图像)
let width = 3;
let height = 3;
let pixel_data: Vec<u8> = vec![
255, 0, 0, // 红色
0, 255, 0, // 绿色
0, 0, 255, // 蓝色
255, 255, 0, // 黄色
255, 0, 255, // 洋红色
0, 255, 255, // 青色
255, 255, 255, // 白色
128, 128, 128, // 灰色
0, 0, 0 // 黑色
];
// 定义源和目标色彩空间
let src_encoding = ColorEncoding::srgb();
let dst_encoding = ColorEncoding::linear_srgb();
// 执行色彩空间转换
let converted_pixels = jxl_color::transform(
&src_encoding,
&dst_encoding,
&pixel_data,
width,
height
)?;
println!("转换成功!输出数据长度: {}", converted_pixels.len());
// 示例2: ICC配置文件处理
println!("\n=== ICC配置文件处理示例 ===");
// 假设有一个ICC配置文件数据
let icc_data = match fs::read("profile.icc") {
Ok(data) => data,
Err(_) => {
println!("ICC文件不存在,使用示例数据");
// 这里使用空的示例数据
Vec::new()
}
};
if !icc_data.is_empty() {
let profile = IccProfile::new(icc_data)?;
let color_encoding = profile.to_color_encoding()?;
println!("ICC配置文件解析成功");
println!("色彩编码: {:?}", color_encoding);
}
// 示例3: 批量处理优化
println!("\n=== 批量处理优化示例 ===");
// 预创建色彩转换器
let transform = ColorTransform::new(
&ColorEncoding::srgb(),
&ColorEncoding::cmyk()
)?;
// 模拟多个图像处理
let images = vec![
(vec![255u8, 0, 0, 0, 255, 0], 2, 1), // 红绿像素
(vec![0, 0, 255, 255, 255, 255], 2, 1), // 蓝白像素
];
for (i, (pixels, width, height)) in images.iter().enumerate() {
match transform.transform(pixels, *width, *height) {
Ok(converted) => {
println!("图像 {} 转换成功,输出长度: {}", i + 1, converted.len());
}
Err(e) => {
eprintln!("图像 {} 转换失败: {}", i + 1, e);
}
}
}
// 示例4: 自定义色彩空间
println!("\n=== 自定义色彩空间示例 ===");
let custom_encoding = ColorEncoding::new(
jxl_color::Primaries::Bt709,
jxl_color::WhitePoint::D65,
jxl_color::TransferFunction::Gamma(2.2),
jxl_color::RenderingIntent::Perceptual
);
println!("自定义色彩空间创建成功: {:?}", custom_encoding);
// 示例5: 错误处理演示
println!("\n=== 错误处理示例 ===");
let invalid_pixels = vec![255u8]; // 无效的像素数据长度
match jxl_color::transform(&src_encoding, &dst_encoding, &invalid_pixels, 1, 1) {
Ok(_) => println!("转换成功"),
Err(Error::InvalidData) => eprintln!("错误: 无效的像素数据"),
Err(e) => eprintln!("其他错误: {}", e),
}
Ok(())
}
// 辅助函数:处理转换后的像素数据
fn process_converted_pixels(pixels: &[u8]) {
println!("处理 {} 字节的像素数据", pixels.len());
// 这里可以添加具体的像素处理逻辑
}
// 单元测试示例
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_srgb_to_linear() {
let src = ColorEncoding::srgb();
let dst = ColorEncoding::linear_srgb();
// 测试黑色像素转换
let black_pixels = vec![0u8, 0, 0];
let result = jxl_color::transform(&src, &dst, &black_pixels, 1, 1).unwrap();
assert_eq!(result.len(), 3);
println!("黑色像素转换测试通过");
}
}
这个完整的示例演示了jxl-color库的主要功能,包括:
- 基本色彩空间转换(sRGB到线性sRGB)
- ICC配置文件处理(包含错误处理)
- 批量图像处理优化
- 自定义色彩空间创建
- 全面的错误处理机制
- 单元测试示例
要运行此示例,需要在Cargo.toml中添加jxl-color依赖,并根据需要准备ICC配置文件。示例代码包含了适当的错误处理和日志输出,方便调试和理解库的使用方式。