Convert color data between color spaces and color formats provided by the maxon API or loaded from disk.
In digital content creation it is often necessary to convert colors between color spaces to ensure faithful representations of colors in different in- and output contexts. A color space defines a representable set of colors with a dedicated purpose. Such purposes could for example be to define a set of colors
The abstract concept of a color space is often implemented in the form of color profiles, most notably in form of International Color Consortium (ICC) color profiles. When colors defined by a color profile must be stored in memory or a file, a color storage format must be chosen, answering questions such as:
RGB
or BGR
.The act of producing, using, and converting between such color spaces and formats is called color management. Another key concept within color management is gamma correction. Humans perceive intensity values non-linearly (Fig. I), while raw data, as provided by a camera or generated by a render engine, is often stored in a linear format.
Color profiles capture this phenomenon in the form of gamma values. In practice, color profiles use a more complex approach called tristimulus values which encodes sensitivity over the three cone cell types of the human eye but this is often hidden away by high level APIs; roughly speaking, tri-stimulus values separate sensitivity over different bins of wave-lengths of light which are handled by one of the cone cell types. When color profiles are associated with gamma values, there is then often the notion of linear and non-linear profiles. A color profile is being considered linear when it has a gamma value of exactly 1.0; and it is being considered non-linear when it has a gamma value not equal to one.
When a set of color values is converted to such non-linear profile, the operation is in non-linear transform, the elements of the converted set will no longer be in the same distance relations as the elements in the original set. Taking the example from Fig. I, the list of greyscale values [0.1, 0.2, 0.5, 0.6]
can be converted with a gamma value of 2.2 into values that more closely align with the human perception of these linear values. The first two values 0.35 and 0.48 are clearly separated, while the last two values 0.73 and 0.79 are almost identical, the distance between these two pairs is no longer the same, as the operation was non-linear. In the inverse operation, one can choose a in a non-linear space and convert them to a set of values which would be considered by humans visually linear within a linear space (Fig. II).
The image.framework provides two high level color management entry points in the form of namespaces.
A color space is represented by the type ColorSpaceInterface and provides only two methods:
A color profile is represented by the type maxon::ColorProfileInterface and its most important methods are:
The classic API type ColorProfile is a thin wrapper around the maxon API type maxon::ColorProfileInterface and the wrapped object can be get and set with the methods GetInternalProfile and SetInternalProfile. For classic API types such as BaseBitmap and ShaderData, one must still pass or retrieves the classic API type, but for computations one should always use the maxon API type.
ColorProfile
. Functions signatures in the image.framework
documentation which return or accept a reference to an maxon::ColorProfileInterface instance, unfortunately often link incorrectly to the classic API type. Meant is here always the interface reference, not the classic API type.Color data associated with a color profile and a pixel format can be converted to a different color profile and/or pixel format with the type ColorProfileConvertInterface, its most important methods are:
The method ColorProfileConvertInterface::Convert makes use of the maxon::ImageBufferTemplate buffer handler aliases:
This construction allows for operating on raw pixel data stored in collection types as maxon::Block or maxon::BaseArray, as opposed to being tied to a specific bitmap data interface as BaseBitmap or ImageBaseInterface. When initializing buffer handlers, it is often most convenient to use the largest possible channel size, maxon::Pix, even when the channel data of a pixel is smaller, as data will then be simply written with a stride.
Articles | OpenColorIO Manual | Convert colors with the color profiles provided by the OpenColorIO (OCIO) configuration of a scene. |
Images Manual | Read and write pixel data with an abstract bitmap interface which can be serialized into multiple file formats. | |
BaseBitmap Manual | Read and write pixel data with an abstract bitmap interface which can be used to display image data in GUIs. | |
Important API Entities | maxon::ColorSpaces | Provides access to abstract color space implementations as for example RGB or CMYK. |
maxon::PixelFormats | Provides access to pixel formats for color spaces as for example RGB, BGR, or CMYK. | |
maxon::ColorSpaceInterface | Represents an abstract color space over a linear and non-linear color profile for the space. | |
maxon::ColorProfileInterface | Represents a concrete color space to carry out color conversions with. | |
ColorProfile | Wraps the type ColorProfileInterface for classic API interfaces. | |
maxon::ColorProfileConvertInterface | Converts pixel data between two color profiles and/or pixel formats. | |
maxon::ImageBufferTemplate | Wraps raw pixel-array buffers for methods in the image.framework . | |
maxon::ImageBaseInterface | Represents a bitmap which can be modified and read and written from disk. | |
BaseBitmap | Wraps the type maxon::ImageBaseInterface, adds drawing functionalities and can be drawn directly into GUIs. | |
SDK Plugins | Color Management Plugin | Contains the examples shown in this manual. |
Examples | Instantiate Builtin Color Profiles | Instantiate color profiles from the builtin color spaces and pixel formats. |
Instantiate Color Profiles from ICC Files | Instantiate color profiles from ICC color profile files and the builtin pixel formats. | |
Read Color Profile Metadata | Read color profile metadata such as description strings and supported pixel formats. | |
Write Color Profiles | Write a color profile object to an ICC color profile file on disk. | |
Access Pixel Formats | Access builtin pixel formats and their associated metadata, such as formatting groups, number of channels, and memory layout per channel. | |
Color Convert Singular Pixels | Convert color data pixel by pixel with color profiles and/or pixel formats. | |
Color Convert Chunks of Pixel Data | Convert color data in chunks of pixels with color profiles and/or pixel formats. | |
Color Convert Bitmap Data | Read color data from a bitmap to a buffer and convert this buffer with color profiles and/or pixel formats. | |
Use Color Conversion Utilities | Convert colors between common color representations such as RGB, HSL, and CMYK. |
The examples shown here are all part of the Color Management Plugin in the SDK. Once the SDK has been compiled and installed, the plugin can be found under the menu entry Extensions\Example.image\C++ SDK: Color Management Examples
.
In order to run the Color Management Plugin plugin, one must provide two ICC files named sRGB2014.icc
and D65_XYZ.icc
in the directory /plugins/example.image/source
of the extended SDK (Fig. III ). Any ICC files can be used in principal, but the intended files are the ICC reference profiles sRGB2014.icc and D65_XYZ.icc from www.color.org (last retrieved 08/11/2022). As of Cinema 4D 2023.2, the color profiles are included with the Extended C++ SDK, but not yet with the SDK delivered with a Cinema 4D installation.
Instantiate color profiles from the builtin color spaces and pixel formats.
Instantiate color profiles from ICC color profile files and the builtin pixel formats.
Read color profile metadata such as description strings and supported pixel formats.
Write a color profile object to an ICC color profile file on disk.
This can also be done with the builtin profiles or any maxon::ColorProfileInterface reference exposed in the APIs. With Cinema 4D 2023.2, this will make it for example possible to serialize an OCIO Display + View transform to disk.
Access builtin pixel formats and their associated metadata, such as formatting groups, number of channels, and memory layout per channel.
Convert color data pixel by pixel with color profiles and/or pixel formats.
This pixel-by-pixel approach is not (considerably) less efficient than converting data in blocks and in fact the dominant form of usage within our own APIs. The advantage is that with this approach one can be less verbose in setting up the conversion handlers.
Convert color data in chunks of pixels with color profiles and/or pixel formats.
This example also picks up the linear to non-linear space conversions example [0.1, 0.2, 0.5, 0.6]
of the Color Management Manual.
Read color data from a bitmap to a buffer and convert this buffer with color profiles and/or pixel formats.
Convert colors between common color representations such as RGB, HSL, and CMYK.