4 个版本

0.0.4 2021年7月8日
0.0.3 2021年7月8日
0.0.2 2021年7月8日
0.0.1 2021年7月8日

#840 in 图像

Apache-2.0

3MB
14K SLoC

OpenEXR

openexr crate 为 ASWF OpenEXR 库 提供高级绑定,允许读取和写入 OpenEXR 格式(EXR 代表 EXtended Range)的文件。OpenEXR 格式是电影行业的实际标准图像存储格式。

EXR 格式的目的是准确和高效地表示高动态范围场景线性图像数据和关联元数据,并强烈支持多部分、多通道用例。

OpenEXR 在需要精确性的宿主应用程序软件中得到广泛使用,例如逼真渲染、纹理访问、图像合成、深度合成和DI。OpenEXR 是 Academy Software Foundation 的一个项目。该格式和库最初由工业光魔公司开发,并于 2003 年首次发布。Weta Digital、Walt Disney Animation Studios、Sony Pictures Imageworks、Pixar Animation Studios、DreamWorks 等工作室、公司和个人都对代码库做出了贡献。

OpenEXR 包含在 VFX 参考平台 中。

openexr crate 由 vfx-rs 项目 维护。

快速入门

要使用包含的 C++ OpenEXR 源代码

cargo add openexr
cargo build

如果您想使用现有的 OpenEXR 安装

cargo add openexr
IMATH_ROOT=/path/to/imath OPENEXR_ROOT=/path/to/openexr cargo build

请注意,您必须确保指向的 OpenEXR 版本与 crate 版本相同,否则由于所有 OpenEXR 符号都有版本号,您将遇到链接器错误。

prelude》引入了您进行基本 RGBA 和任意通道图像文件 I/O 所需的类型集合

use openexr::prelude::*;

fn write_rgba1(filename: &str, pixels: &[Rgba], width: i32, height: i32)
-> Result<(), Box<dyn std::error::Error>> {
    let header = Header::from_dimensions(width, height);
    let mut file = RgbaOutputFile::new(
        filename,
        &header,
        RgbaChannels::WriteRgba,
        1,
    )?;

    file.set_frame_buffer(&pixels, 1, width as usize)?;
    file.write_pixels(height)?;

    Ok(())
}

fn read_rgba1(path: &str) -> Result<(), Box<dyn std::error::Error>> {
    use imath_traits::Zero;

    let mut file = RgbaInputFile::new(path, 1).unwrap();
    // Note that windows in OpenEXR are ***inclusive*** bounds, so a
    // 1920x1080 image has window [0, 0, 1919, 1079].
    let data_window: [i32; 4] = *file.header().data_window();
    let width = data_window.width() + 1;
    let height = data_window.height() + 1;

    let mut pixels = vec![Rgba::zero(); (width * height) as usize];
    file.set_frame_buffer(&mut pixels, 1, width as usize)?;
    file.read_pixels(0, height - 1)?;

    Ok(())
}

除此之外,与深度图像相关的类型在 deep 模块中,而分块图像在 tiled 模块中。

读取和写入 OpenEXR 图像文件》文档是一个很好的起点,可以探索 crate 的全部功能。它包含了几乎所有内容的示例用法。

数学 crate 兼容性

OpenEXR(以及 VFX 生态系统的很大一部分)依赖于 Imath 提供基本的数学原语,如向量和边界框。

Rust 已经有几个成熟的线性代数库,针对图形应用,如 cgmathnalgebranalgebra-glmglam。我们不是在这个竞争激烈的领域再添加另一个竞争者,而是提供一套特性,允许这些库以 imath-traits 的形式与 openexr 一起使用。默认情况下,这些特性为数组和切片实现,因此你会发现本文档中的示例倾向于使用例如 [i32; 4] 的方式来表示边界框。

    let mut file = RgbaInputFile::new(path, 1).unwrap();
    let data_window = file.header().data_window::<[i32; 4]>().clone();
    let width = data_window.width() + 1;
    let height = data_window.height() + 1;

要使用您首选的数学库,只需在 openexr 中启用相应的功能,这将是 imath_<name>,例如

cargo build --features=imath_cgmath

现在您可以使用该库中的类型与 openexr 无缝地一起使用。如果数学库没有提供边界框类型,则可以使用 imath_traits::Box2iimath_traits::Box3i 来使用。

    use imath_traits::Box2i;

    let mut file = RgbaInputFile::new(path, 1).unwrap();
    let data_window: Box2i = *file.header().data_window();
    let width = data_window.width() + 1;
    let height = data_window.height() + 1;

特性

  • 高动态范围和颜色精度。
  • 支持 16 位浮点数、32 位浮点数和 32 位整数像素。
  • 多种图像压缩算法,包括无损和有损。其中一些包含的编解码器可以在具有电影颗粒的图像上实现 2:1 的无损压缩比率。有损编解码器已针对视觉质量和解码性能进行调整。
  • 可扩展性。可以在不影响现有 OpenEXR 应用程序的向后兼容性的情况下,将新的图像属性(字符串、向量、整数等)添加到 OpenEXR 图像头中。
  • 支持立体图像工作流程和扩展到多视图。
  • 对深度数据的灵活支持:像素可以存储可变长度的样本列表,因此可以为每个像素存储不同深度的多个值。硬表面和体积数据表示形式都得到支持。
  • 多部分:能够在单个文件中编码单独但相关的图像。这允许访问单个部分,而无需读取文件中的其他部分。

长篇文档

以下文档提供了对 openexr 库不同部分的更深入了解

构建文档

要构建包括长篇文档和 KaTeX 公式的完整文档,请使用以下命令

cargo +nightly doc --no-deps --features=long-form-docs

请注意,这是在发布到 docs.rs 时自动执行的。

要运行长篇文档中的 doctests(即确保代码示例正确编译),请运行

cargo +nightly test --features=long-form-docs

一旦 Rust 1.54 发布,这将不再必要。

依赖关系

~4.5–7MB
~170K SLoC