Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve examples & (api-breaking) rename some constant #154

Merged
merged 5 commits into from
May 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
*.png
testout
/.run
.vscode
.vscode
*.exr
pngs/
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,22 +174,36 @@ so you could also link the github repository master branch.

### Example

Example: [generate an rgb exr file](https://github.com/johannesvollmer/exrs/blob/master/examples/0_minimal_rgb_write.rs).
Example: [generate an rgb exr file](https://github.com/johannesvollmer/exrs/blob/master/examples/0_write_rgba.rs).

```rust
extern crate exr;

/// To write your image data, you need to specify how to retrieve a single pixel from it.
/// The closure may capture variables or generate data on the fly.
fn main() {
// write a file with 16-bit alpha and 32-bit color precision
exr::prelude::write_rgba_file(
"tests/images/out/minimal_rgb.exr",
2048, 2048, // write an image with 2048x2048 pixels
|x,y| ( // generate (or lookup in your own image) an f32 rgb color for each of the 2048x2048 pixels
use exr::prelude::*;

// write a file, with 32-bit float precision per channel
write_rgba_file(

// this accepts paths or &str
"minimal_rgba.exr",

// image resolution is 2k
2048, 2048,

// generate (or lookup in your own image)
// an f32 rgb color for each of the 2048x2048 pixels
|x,y| {
(
x as f32 / 2048.0, // red
y as f32 / 2048.0, // green
1.0 - (y as f32 / 2048.0), // blue
f16::from_f32(0.8) // 16-bit alpha
)
1.0 // alpha
)
}

).unwrap();
}
```
Expand Down
23 changes: 0 additions & 23 deletions examples/0_minimal_rgb_write.rs

This file was deleted.

35 changes: 35 additions & 0 deletions examples/0a_write_rgba.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
extern crate exr;


/// `exr` offers a few simplified functions for the most basic use cases.
/// `write_rgb_f32_file` is a such a function, which writes a plain rgba exr file.
///
/// To write your image data, you need to specify how to retrieve a single pixel from it.
/// The closure may capture variables or generate data on the fly.
fn main() {
use exr::prelude::*;

// write a file, with 32-bit float precision per channel
write_rgba_file(

// this accepts paths or &str
"minimal_rgba.exr",

// image resolution is 2k
2048, 2048,

// generate (or lookup in your own image)
// an f32 rgb color for each of the 2048x2048 pixels
|x,y| {
(
x as f32 / 2048.0, // red
y as f32 / 2048.0, // green
1.0 - (y as f32 / 2048.0), // blue
1.0 // alpha
)
}

).unwrap();

println!("created file minimal_rgb.exr");
}
4 changes: 2 additions & 2 deletions examples/0_read_meta.rs → examples/0b_read_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ fn main() {
use exr::prelude::*;

let meta_data = MetaData::read_from_file(
"tests/images/valid/custom/crowskull/crow_uncompressed.exr",
"generated_rgba_with_meta.exr",
false // do not throw an error for invalid or missing attributes, skipping them instead
).unwrap();
).expect("run example `1_write_rgba_with_metadata` to generate the required file");

for (layer_index, image_layer) in meta_data.headers.iter().enumerate() {
println!(
Expand Down
13 changes: 7 additions & 6 deletions examples/0_minimal_rgb_read.rs → examples/0c_read_rgba.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
extern crate exr;

/// `exr` offers a few very simple functions for the most basic use cases.
/// `read_first_rgba_layer_from_file` is a simple function which loads an exr file.
/// To load the image, you need to specify how to create and how to update your image.
/// `exr` offers a few simplified functions for the most basic use cases.
/// `read_first_rgba_layer_from_file` is a such a function, which loads rgba exr files.
/// To load the pixel data, you need to specify
/// how to create and how to set the pixels of your image.
fn main() {
let image = exr::prelude::read_first_rgba_layer_from_file(
"tests/images/out/generated_rgba.exr", // run the `1_generate_rgba` example to generate this file
"generated_rgba.exr",

// instantiate your image type with the size of the image file
// instantiate your image type with the size of the image in file
|resolution, _| {
let default_pixel = [0.0, 0.0, 0.0, 0.0];
let empty_line = vec![ default_pixel; resolution.width() ];
Expand All @@ -22,7 +23,7 @@ fn main() {
pixel_vector[position.y()][position.x()] = [r, g, b, a]
},

).unwrap();
).expect("run the `1_write_rgba` example to generate the required file");

// printing all pixels might kill the console, so only print some meta data about the image
println!("opened file generated_rgba.exr: {:#?}", image.layer_data.attributes);
Expand Down
55 changes: 0 additions & 55 deletions examples/1_generate_rgba.rs

This file was deleted.

64 changes: 64 additions & 0 deletions examples/1a_write_rgba_with_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

// exr imports
extern crate exr;

/// Write an rgba exr file, generating the pixel values on the fly.
/// This streams the generated pixel directly to the file,
/// never allocating the actual total pixel memory of the image.
fn main() {
use exr::prelude::*;
use exr::meta::attribute::*;

// this function can generate a color for any pixel
let generate_pixels = |position: Vec2<usize>| (
position.x() as f32 / 2048.0, // red
position.y() as f32 / 2048.0, // green
1.0 - (position.y() as f32 / 2048.0), // blue
1.0 // alpha
);

let mut layer_attributes = LayerAttributes::named("generated rgba main layer");
layer_attributes.comments = Some(Text::from("This image was generated as part of an example"));
layer_attributes.owner = Some(Text::from("The holy lambda function"));
layer_attributes.software_name = Some(Text::from("EXRS Project"));
layer_attributes.exposure = Some(1.0);
layer_attributes.focus = Some(12.4);
layer_attributes.frames_per_second = Some((60, 1));
layer_attributes.other.insert(
Text::from("Layer Purpose (Custom Layer Attribute)"),
AttributeValue::Text(Text::from("This layer contains the rgb pixel data"))
);

let layer = Layer::new(
(2*2048, 2*2048),
layer_attributes,
Encoding::SMALL_FAST_LOSSLESS, // use fast but lossy compression

SpecificChannels::rgba(generate_pixels)
);

// crop away black and transparent pixels from the border, if any
let layer = layer
.crop_where_eq((0.0, 0.0, 0.0, 0.0))
.or_crop_to_1x1_if_empty();

let mut image = Image::from_layer(layer);
image.attributes.pixel_aspect = 1.0;

image.attributes.time_code = Some(TimeCode {
hours: 0,
minutes: 1,
seconds: 59,
frame: 29,
..TimeCode::default()
});

image.attributes.other.insert(
Text::from("Mice Count (Custom Image Attribute)"),
AttributeValue::I32(23333)
);

// write it to a file with all cores in parallel
image.write().to_file("generated_rgba_with_meta.exr").unwrap();
println!("created file generated_rgba_with_meta.exr");
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extern crate image as png;
// exr imports
extern crate exr;

/// Converts one rgba exr with one layer to one png, or fail.
fn main() {
use exr::prelude::*;
use exr::prelude as exrs;
Expand Down Expand Up @@ -33,8 +34,8 @@ fn main() {

// an image that contains a single layer containing an png rgba buffer
let image: Image<Layer<SpecificChannels<png::RgbaImage, RgbaChannels>>> = reader
.from_file("tests/images/valid/openexr/MultiResolution/Kapaa.exr")
.unwrap();
.from_file("generated_rgba.exr")
.expect("run the `1_write_rgba` example to generate the required file");


/// compress any possible f32 into the range of [0,1].
Expand All @@ -47,6 +48,6 @@ fn main() {

// save the png buffer to a png file
let png_buffer = &image.layer_data.channel_data.pixels;
png_buffer.save("tests/images/out/rgb.png").unwrap();
png_buffer.save("rgb.png").unwrap();
println!("created image rgb.png")
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ fn main() {
)
.first_valid_layer()
.all_attributes()
.from_file("tests/images/valid/openexr/MultiResolution/Kapaa.exr")
.unwrap();
.from_file("generated_rgba.exr")
.expect("run the `1_write_rgba` example to generate the required file");

let exposure_multiplier = 2.0;

Expand Down Expand Up @@ -71,10 +71,10 @@ fn main() {
}
}

// write the image to a file
// write the image to a file
image
.write().to_file("tests/images/out/exposure_adjusted.exr")
.write().to_file("rgba_exposure_adjusted.exr")
.unwrap();

println!("created file exposure_adjusted.exr");
println!("created file rgba_exposure_adjusted.exr");
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use rand::Rng;
extern crate exr;


/// Generate a noisy image and write it to a file.
/// Generate a noisy image and write it to a file,
/// also attaching some meta data.
fn main() {
use exr::prelude::*;

Expand Down Expand Up @@ -71,7 +72,7 @@ fn main() {

image.write()
.on_progress(|progress| println!("progress: {:.1}", progress*100.0))
.to_file("tests/images/out/noisy.exr").unwrap();
.to_file("noisy.exr").unwrap();

println!("created file noisy.exr");
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ extern crate exr;

/// Read an image and print information about the image into the console.
/// This example shows how to read an image with multiple layers and arbitrary channels.
/// For example, a layer with XYZ channels, and additionally a separate Depth layer.
/// This example does not include resolution levels (mipmaps or ripmaps).
fn main() {
use exr::prelude::*;

let image = read().no_deep_data()
.largest_resolution_level().all_channels().all_layers().all_attributes()
.on_progress(|progress| println!("progress: {:.1}", progress*100.0))
.from_file("tests/images/valid/openexr/Beachball/multipart.0004.exr")
.unwrap();
.from_file("generated_rgba_with_meta.exr")
.expect("run example `1_write_rgba_with_metadata` to generate this image file");

println!("image was read: {:#?}", image);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn main() {

let pixels = SpecificChannels::build()
.with_channel("Kharthanasus Korthus")
.with_channel(" Trochäus ")
.with_channel("Y")
.with_channel("11023")
.with_channel("*?!")
.with_channel("`--\"")
Expand All @@ -35,7 +35,7 @@ fn main() {
println!("progress: {}%", current_progress_percentage)
}
})
.to_file("tests/images/out/strange_channels.exr").unwrap();
.to_file("custom_channels.exr").unwrap();

println!("created file strange_channels.exr");
println!("created file custom_channels.exr");
}
Loading