class new in Git master
OpenExrImageConverterOpenEXR image converter plugin.
Creates OpenEXR (*.exr
) files from 2D and cubemap images with optional mip levels and PixelFormat::
Usage
This plugin depends on the Trade library and is built if MAGNUM_WITH_OPENEXRIMAGECONVERTER
is enabled when building Magnum Plugins. To use as a dynamic plugin, load "OpenExrImageConverter"
via Corrade::
Additionally, if you're using Magnum as a CMake subproject, bundle the magnum-plugins and openexr repositories (pin OpenEXR at v3.0.1
at least) and do the following. OpenEXR depends on zlib and Imath, however it's capable of fetching those dependencies on its own so bundling them isn't necessary. If you want to use system-installed OpenEXR, omit the first part and point CMAKE_PREFIX_PATH
to its installation dir if necessary.
# Disable unneeded functionality set(PYILMBASE_ENABLE OFF CACHE BOOL "" FORCE) set(IMATH_INSTALL_PKG_CONFIG OFF CACHE BOOL "" FORCE) set(IMATH_INSTALL_SYM_LINK OFF CACHE BOOL "" FORCE) set(OPENEXR_INSTALL OFF CACHE BOOL "" FORCE) set(OPENEXR_INSTALL_DOCS OFF CACHE BOOL "" FORCE) set(OPENEXR_INSTALL_EXAMPLES OFF CACHE BOOL "" FORCE) set(OPENEXR_INSTALL_PKG_CONFIG OFF CACHE BOOL "" FORCE) set(OPENEXR_INSTALL_TOOLS OFF CACHE BOOL "" FORCE) set(OPENEXR_BUILD_UTILS OFF CACHE BOOL "" FORCE) # Otherwise OpenEXR uses C++14, and before OpenEXR 3.0.2 also forces C++14 on # all libraries that link to it. set(OPENEXR_CXX_STANDARD 11 CACHE STRING "" FORCE) # OpenEXR implicitly bundles Imath. However, without this only the first CMake # run will pass and subsequent runs will fail. set(CMAKE_DISABLE_FIND_PACKAGE_Imath ON) # These variables may be used by other projects, so ensure they're reset back # to their original values after. OpenEXR forces CMAKE_DEBUG_POSTFIX to _d, # which isn't desired outside of that library. set(_PREV_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) set(_PREV_BUILD_TESTING ${BUILD_TESTING}) set(BUILD_SHARED_LIBS OFF) set(BUILD_TESTING OFF) set(CMAKE_DEBUG_POSTFIX "" CACHE STRING "" FORCE) add_subdirectory(openexr EXCLUDE_FROM_ALL) set(BUILD_SHARED_LIBS ${_PREV_BUILD_SHARED_LIBS}) set(BUILD_TESTING ${_PREV_BUILD_TESTING}) unset(CMAKE_DEBUG_POSTFIX CACHE) set(MAGNUM_WITH_OPENEXRIMAGECONVERTER ON CACHE BOOL "" FORCE) add_subdirectory(magnum-plugins EXCLUDE_FROM_ALL) # So the dynamically loaded plugin gets built implicitly add_dependencies(your-app MagnumPlugins::OpenExrImageConverter)
To use as a static plugin or as a dependency of another plugin with CMake, put FindMagnumPlugins.cmake and FindOpenEXR.cmake into your modules/
directory, request the OpenExrImageConverter
component of the MagnumPlugins
package and link to the MagnumPlugins::OpenExrImageConverter
target:
find_package(MagnumPlugins REQUIRED OpenExrImageConverter) # ... target_link_libraries(your-app PRIVATE MagnumPlugins::OpenExrImageConverter)
See Downloading and building plugins, Plugin usage with CMake, Loading and using plugins and File format support for more information.
Behavior and limitations
As OpenEXR doesn't have a registered MIME type, mimeType() returns "image/x-exr"
.
The plugin recognizes ImageConverterFlag::
Channel mapping
Images with PixelFormat::R
, G
, B
and A
; images with PixelFormat::Z
channel.
If the default behavior is not sufficient, custom channel mapping can be supplied in the configuration.
Multilayer and multipart images, deep images
Channels can be prefixed with a custom layer name by specifying the layer
configuration option. Combining multiple layers into a single image isn't supported right now, writing multipart files or deep images is not supported either.
Cube and lat/lon environment maps
A 2D image can be annotated as being a lat/lon environment map by setting envmap=latlon
in the configuration. This requires it to have the width twice of the height.
A cube map image can be saved from an ImageView3D where each slice is one face in order +X, -X, +Y, -Y, +Z and -Z if you set envmap=cube
. In this case, the image is expected to have six rectangular faces.
Array and 3D images
Apart from cube maps, saving of arbitrary 3D and 2D array (or "deep") images isn't implemented right now.
The OpenEXR file format doesn't have a way to distinguish between 2D and 1D array images. If an image has ImageFlag2D::
Multilevel images
Both 2D and cube map images can be saved with multiple levels by using the list variants of convertToFile() / convertToData(). Largest level is expected to be first, with each following level having width and height divided by two, rounded down. Cube map images additionally have the restrictions specified above. OpenEXR has no builtin concept of an incomplete mip chain, unspecified levels at the end result in a file with missing tiles. This may cause problems with 3rd party tools, however the OpenExrImporter detects such case and reports the file as having less levels.
Multilevel images result in a tiled OpenEXR file, with a tile size taken from the tileSize
configuration option. Single-level images are implicitly written as scanline files, you can override that with the forceTiledOutput
option.
Plugin-specific configuration
It's possible to tune various options mainly for channel mapping through configuration(). See below for all options and their default values:
[configuration] # Number of threads OpenEXR should use for compression and writing. A value # of 1 performs compression and writing serially in the calling thread, 2 # adds one additional worker thread for compression, etc. 0 sets it to the # value returned by std::thread::hardware_concurrency(). # # Note that while the amount of threads can be controlled per-file, OpenEXR # has a global thread pool and its size will remain at the largest set value # until the plugin is unloaded. OpenExrImporter shares the same thread pool. threads=1 # Save channels with given layer layer= # Map R/RG/RGB/RGBA image channels to given channel names. If the image is in # a PixelFormat::Depth32F, depth is used instead. If the channel is not # present in the input or if its name is empty, it's not written to the file. r=R g=G b=B a=A depth=Z # Set to latlong for 2D images to annotate the image as a lat/long # environment map. If empty, no environment map metadata are saved. 3D images # should instead have ImageFlag3D::CubeMap set to be saved as a cube map. envmap= # Display and data window. OpenEXR allows the image to annotate a crop border # or specify that the data are just a small portion of a bigger image. The # display window is a four-component vector with (inclusive) Xmin, Ymin, # Xmax, Ymax coordinates. If left empty, it's implicitly set to 0 0 width-1 # height-1. The data window size is always set to width-1 height-1 and you # can only set the offset. For details see the pixel space, see here: # https://openexr.readthedocs.io/en/latest/TechnicalIntroduction.html#display-window displayWindow= dataOffset=0 0 # Compression. Allowed values are rle, zip, zips, piz, pxr24, b44, b44a, dwaa # and dwab; leave it empty to write the output uncompressed. More info here: # https://openexr.readthedocs.io/en/latest/TechnicalIntroduction.html#data-compression compression=zip # ZIP compression level. Available since OpenEXR 3.1.3, older versions have # it hardcoded to Z_DEFAULT_COMPRESSION, which is 6. zipCompressionLevel=4 # DWA compression level dwaCompressionLevel=45.0 # OpenEXR files with mipmaps are always tiled, single level is implicitly # written as scanlines, unless this option is enabled. Tile size 32x32 is # library default, larger sizes may lead to less overhead and better # compression ratios at the cost of more unused space at smallest image # levels. forceTiledOutput=false tileSize=32 32
See Editing plugin-specific configuration for more information and an example showing how to edit the configuration values.
Enabling multithreading
On Linux it may happen that setting the threads
option to something else than 1
will cause std::pthread
instead. With CMake it can be done like this:
find_package(Threads REQUIRED) target_link_libraries(your-application PRIVATE Threads::Threads)
Base classes
- class AbstractImageConverter
- Base for image converter plugins.
Constructors, destructors, conversion operators
-
OpenExrImageConverter(PluginManager::
AbstractManager& manager, const Containers:: StringView& plugin) explicit - Plugin manager constructor.