Source code for colour.io.ocio

"""
OpenColorIO Processing
======================

Defines the object for *OpenColorIO* processing:

-   :func:`colour.io.process_image_OpenColorIO`
"""

from __future__ import annotations

import numpy as np

from colour.io import as_3_channels_image
from colour.hints import Any, ArrayLike, FloatingOrNDArray
from colour.utilities import as_float_array, as_float_scalar, required

__author__ = "Colour Developers"
__copyright__ = "Copyright 2013 Colour Developers"
__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "colour-developers@colour-science.org"
__status__ = "Production"

__all__ = [
    "process_image_OpenColorIO",
]


# TODO: Reinstate coverage and doctests when "Pypi" wheel compatible with "ARM"
#  on "macOS" is released.


[docs]@required("OpenColorIO") def process_image_OpenColorIO( a: ArrayLike, *args: Any, **kwargs: Any ) -> FloatingOrNDArray: # pragma: no cover """ Process given image data with *OpenColorIO*. Parameters ---------- a Image data to process with *OpenColorIO*. Other Parameters ---------------- config *OpenColorIO* config to use for processing. If not defined, the *OpenColorIO* set defined by the ``$OCIO`` environment variable is used. args Arguments for `Config.getProcessor` method. See https://opencolorio.readthedocs.io/en/latest/api/config.html for more information. Returns ------- :class:`numpy.ndarray` Processed image data. Examples -------- >>> import os >>> import PyOpenColorIO as ocio # doctest: +SKIP >>> from colour.utilities import full >>> config = os.path.join( ... os.path.dirname(__file__), 'tests', 'resources', ... 'config-aces-reference.ocio.yaml') >>> a = 0.18 >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) 0.4135884... >>> a = np.array([0.18]) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) array([ 0.4135884...]) >>> a = np.array([0.18, 0.18, 0.18]) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) array([ 0.4135884..., 0.4135884..., 0.4135884...]) >>> a = np.array([[0.18, 0.18, 0.18]]) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) array([[ 0.4135884..., 0.4135884..., 0.4135884...]]) >>> a = np.array([[[0.18, 0.18, 0.18]]]) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) array([[[ 0.4135884..., 0.4135884..., 0.4135884...]]]) >>> a = full([4, 2, 3], 0.18) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'ACES - ACEScct', config=config) array([[[ 0.4135884..., 0.4135884..., 0.4135884...], [ 0.4135884..., 0.4135884..., 0.4135884...]], <BLANKLINE> [[ 0.4135884..., 0.4135884..., 0.4135884...], [ 0.4135884..., 0.4135884..., 0.4135884...]], <BLANKLINE> [[ 0.4135884..., 0.4135884..., 0.4135884...], [ 0.4135884..., 0.4135884..., 0.4135884...]], <BLANKLINE> [[ 0.4135884..., 0.4135884..., 0.4135884...], [ 0.4135884..., 0.4135884..., 0.4135884...]]]) >>> process_image_OpenColorIO( # doctest: +SKIP ... a, 'ACES - ACES2065-1', 'Display - sRGB', ... 'Output - SDR Video - ACES 1.0', ocio.TRANSFORM_DIR_FORWARD, ... config=config) array([[[ 0.3559542..., 0.3559542..., 0.3559542...], [ 0.3559542..., 0.3559542..., 0.3559542...]], <BLANKLINE> [[ 0.3559542..., 0.3559542..., 0.3559542...], [ 0.3559542..., 0.3559542..., 0.3559542...]], <BLANKLINE> [[ 0.3559542..., 0.3559542..., 0.3559542...], [ 0.3559542..., 0.3559542..., 0.3559542...]], <BLANKLINE> [[ 0.3559542..., 0.3559542..., 0.3559542...], [ 0.3559542..., 0.3559542..., 0.3559542...]]]) """ import PyOpenColorIO as ocio config = kwargs.get("config") config = ( ocio.Config.CreateFromEnv() if config is None else ocio.Config.CreateFromFile(config) ) a = as_float_array(a) shape, dtype = a.shape, a.dtype a = as_3_channels_image(a).astype(np.float32) height, width, channels = a.shape processor = config.getProcessor(*args).getDefaultCPUProcessor() image_desc = ocio.PackedImageDesc(a, width, height, channels) processor.apply(image_desc) b = image_desc.getData().reshape([height, width, channels]).astype(dtype) if len(shape) == 0: return as_float_scalar(np.squeeze(b)[0]) elif shape[-1] == 1: return np.reshape(b[..., 0], shape) else: return np.reshape(b, shape)