Exemplo n.º 1
0
    def test_write_image_OpenImageIO(self):  # pragma: no cover
        """
        Tests :func:`colour.io.image.write_image_OpenImageIO` definition.
        """

        if not is_openimageio_installed():
            return

        source_image_path = os.path.join(RESOURCES_DIRECTORY,
                                         'CMS_Test_Pattern.exr')
        target_image_path = os.path.join(self._temporary_directory,
                                         'CMS_Test_Pattern.exr')
        image = read_image_OpenImageIO(source_image_path)
        write_image_OpenImageIO(image, target_image_path)
        image = read_image_OpenImageIO(target_image_path)
        self.assertTupleEqual(image.shape, (1267, 1274, 3))
        self.assertIs(image.dtype, np.dtype('float32'))

        write_image_OpenImageIO(
            image,
            target_image_path,
            attributes=[ImageAttribute_Specification('John', 'Doe')])
        image, attributes = read_image_OpenImageIO(
            target_image_path, attributes=True)
        for attribute in attributes:
            if attribute.name == 'John':
                self.assertEqual(attribute.value, 'Doe')
Exemplo n.º 2
0
def read_image(path, bit_depth='float32', attributes=False):
    """
    Reads given image using *OpenImageIO*.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.
    attributes : bool, optional
        Whether to return the image attributes.

    Returns
    -------
    ndarray
        Image as a ndarray.

    Notes
    -----
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageInput

        path = str(path)

        bit_depth = BIT_DEPTH_MAPPING[bit_depth].openimageio

        image = ImageInput.open(path)
        specification = image.spec()

        shape = (specification.height, specification.width,
                 specification.nchannels)

        image_data = image.read_image(bit_depth)
        image.close()
        image = np.squeeze(np.array(image_data).reshape(shape))

        if attributes:
            extra_attributes = []
            for i in range(len(specification.extra_attribs)):
                attribute = specification.extra_attribs[i]
                extra_attributes.append(
                    ImageAttribute_Specification(attribute.name,
                                                 attribute.value,
                                                 attribute.type))

            return image, extra_attributes
        else:
            return image
Exemplo n.º 3
0
def read_image(path, bit_depth='float32', attributes=False):
    """
    Reads given image using *OpenImageIO*.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.
    attributes : bool, optional
        Whether to return the image attributes.

    Returns
    -------
    ndarray
        Image as a ndarray.

    Notes
    -----
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageInput

        path = str(path)

        bit_depth = BIT_DEPTH_MAPPING[bit_depth].openimageio

        image = ImageInput.open(path)
        specification = image.spec()

        shape = (specification.height, specification.width,
                 specification.nchannels)

        image_data = image.read_image(bit_depth)
        image.close()
        image = np.squeeze(np.array(image_data).reshape(shape))

        if attributes:
            extra_attributes = []
            for i in range(len(specification.extra_attribs)):
                attribute = specification.extra_attribs[i]
                extra_attributes.append(
                    ImageAttribute_Specification(
                        attribute.name, attribute.value, attribute.type))

            return image, extra_attributes
        else:
            return image
Exemplo n.º 4
0
    def test_read_image_OpenImageIO(self):  # pragma: no cover
        """Test :func:`colour.io.image.read_image_OpenImageIO` definition."""

        if not is_openimageio_installed():
            return

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "CMS_Test_Pattern.exr"))
        self.assertTupleEqual(image.shape, (1267, 1274, 3))
        self.assertIs(image.dtype, np.dtype("float32"))

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "CMS_Test_Pattern.exr"),
            "float16",
        )
        self.assertIs(image.dtype, np.dtype("float16"))

        image, attributes = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "CMS_Test_Pattern.exr"),
            attributes=True,
        )
        self.assertTupleEqual(image.shape, (1267, 1274, 3))
        self.assertEqual(attributes[0].name, "oiio:ColorSpace")
        self.assertEqual(attributes[0].value, "Linear")

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "Single_Channel.exr"))
        self.assertTupleEqual(image.shape, (256, 256))

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "Colour_Logo.png"), "uint8")
        self.assertTupleEqual(image.shape, (128, 256, 4))
        self.assertIs(image.dtype, np.dtype("uint8"))
        self.assertEqual(np.min(image), 0)
        self.assertEqual(np.max(image), 255)

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "Colour_Logo.png"), "uint16")
        self.assertTupleEqual(image.shape, (128, 256, 4))
        self.assertIs(image.dtype, np.dtype("uint16"))
        self.assertEqual(np.min(image), 0)
        self.assertEqual(np.max(image), 65535)

        # TODO: Investigate "OIIO" behaviour here: 1.0 != 15360.0
        # image = read_image_OpenImageIO(
        #     os.path.join(RESOURCES_DIRECTORY, 'Colour_Logo.png'), 'float16')
        # self.assertIs(image.dtype, np.dtype('float16'))
        # self.assertEqual(np.min(image), 0.0)
        # self.assertEqual(np.max(image), 1.0)

        image = read_image_OpenImageIO(
            os.path.join(RESOURCES_DIRECTORY, "Colour_Logo.png"), "float32")
        self.assertIs(image.dtype, np.dtype("float32"))
        self.assertEqual(np.min(image), 0.0)
        self.assertEqual(np.max(image), 1.0)
Exemplo n.º 5
0
def write_image(image, path, bit_depth='float32'):
    """
    Writes given image using *OpenImageIO*.

    Parameters
    ----------
    image : array_like
        Image data.
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image_as_array(path)  # doctest: +SKIP
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.png')
    >>> write_image(image, path, 'uint8')  # doctest: +SKIP
    True
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec

        bit_depth_specification = BIT_DEPTH_MAPPING.get(bit_depth)
        bit_depth = bit_depth_specification.openimageio

        image = np.asarray(image)
        image *= bit_depth_specification.domain
        if bit_depth_specification.clip:
            image = np.clip(image, 0, bit_depth_specification.domain)
        image = image.astype(bit_depth_specification.numpy)

        if image.ndim == 2:
            height, width = image.shape
            channels = 1
        else:
            height, width, channels = image.shape
        specification = ImageSpec(width, height, channels, bit_depth)

        image_output = ImageOutput.create(path)
        image_output.open(path, specification, ImageOutputOpenMode.Create)
        image_output.write_image(bit_depth, image.tostring())
        image_output.close()

        return True
Exemplo n.º 6
0
def write_image(image, path, bit_depth='float32'):
    """
    Writes given image using *OpenImageIO*.

    Parameters
    ----------
    image : array_like
        Image data.
    path : unicode
        Image path.
    bit_depth : unicode, optional
        {'float32', 'uint8', 'uint16', 'float16'}
        Image bit_depth.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image_as_array(path)  # doctest: +SKIP
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.png')
    >>> write_image(image, path, 'uint8')  # doctest: +SKIP
    True
    """

    if image.ndim != 3:
        raise ValueError(
            'Image must have exactly 3 dimensions!')

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec

        bit_depth_specification = BIT_DEPTH_MAPPING.get(bit_depth)
        bit_depth = bit_depth_specification.openimageio

        image = np.asarray(image)
        image *= bit_depth_specification.domain
        if bit_depth_specification.clip:
            image = np.clip(image, 0, bit_depth_specification.domain)
        image = image.astype(bit_depth_specification.numpy)

        height, width, channels = image.shape
        specification = ImageSpec(width, height, channels, bit_depth)

        image_output = ImageOutput.create(path)
        image_output.open(path, specification, ImageOutputOpenMode.Create)
        image_output.write_image(bit_depth, image.tostring())
        image_output.close()

        return True
Exemplo n.º 7
0
def read_image(path, bit_depth='float32'):
    """
    Reads given image using *OpenImageIO*.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.

    Returns
    -------
    ndarray
        Image as a ndarray.

    Notes
    -----
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image_as_array(path)  # doctest: +SKIP
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageInput

        bit_depth = BIT_DEPTH_MAPPING.get(bit_depth).openimageio

        image = ImageInput.open(path)
        specification = image.spec()

        shape = (specification.height,
                 specification.width,
                 specification.nchannels)

        return np.squeeze(np.array(image.read_image(bit_depth)).reshape(shape))
Exemplo n.º 8
0
def read_image(path, bit_depth='float32'):
    """
    Reads given image using *OpenImageIO*.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.

    Returns
    -------
    ndarray
        Image as a ndarray.

    Notes
    -----
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image_as_array(path)  # doctest: +SKIP
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageInput

        bit_depth = BIT_DEPTH_MAPPING.get(bit_depth).openimageio

        image = ImageInput.open(path)
        specification = image.spec()

        shape = (specification.height, specification.width,
                 specification.nchannels)

        return np.squeeze(np.array(image.read_image(bit_depth)).reshape(shape))
Exemplo n.º 9
0
Arquivo: image.py Projeto: yixw/colour
def write_image_OpenImageIO(image, path, bit_depth='float32', attributes=None):
    """
    Writes given image at given path using *OpenImageIO*.

    Parameters
    ----------
    image : array_like
        Image data.
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Bit depth to write the image at, the bit depth conversion behaviour is
        ruled directly by *OpenImageIO*.
    attributes : array_like, optional
        An array of :class:`colour.io.ImageAttribute_Specification` class
        instances used to set attributes of the image.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    Basic image writing:

    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMSTestPattern.tif')
    >>> write_image(image, path)  # doctest: +SKIP
    True

    Advanced image writing while setting attributes:

    >>> compression = ImageAttribute_Specification('Compression', 'none')
    >>> write_image(image, path, 'uint8', [compression])  # doctest: +SKIP
    True
    """

    if is_openimageio_installed(raise_exception=True):  # pragma: no cover
        from OpenImageIO import VERSION_MAJOR, ImageOutput, ImageSpec

        path = str(path)

        if attributes is None:
            attributes = []

        bit_depth_specification = BIT_DEPTH_MAPPING[bit_depth]
        bit_depth = bit_depth_specification.openimageio

        image = as_float_array(image)
        image = image * bit_depth_specification.domain
        if bit_depth_specification.clip:
            image = np.clip(image, 0, bit_depth_specification.domain)
        image = image.astype(bit_depth_specification.numpy)

        if image.ndim == 2:
            height, width = image.shape
            channels = 1
        else:
            height, width, channels = image.shape

        specification = ImageSpec(width, height, channels, bit_depth)
        for attribute in attributes:
            name = str(attribute.name)
            value = (str(attribute.value) if isinstance(
                attribute.value, string_types) else attribute.value)
            type_ = attribute.type_
            if attribute.type_ is None:
                specification.attribute(name, value)
            else:
                specification.attribute(name, type_, value)

        image_output = ImageOutput.create(path)

        if VERSION_MAJOR == 1:
            from OpenImageIO import ImageOutputOpenMode

            image_output.open(path, specification, ImageOutputOpenMode.Create)
            image_output.write_image(bit_depth, image.tostring())
        else:
            image_output.open(path, specification)
            image_output.write_image(image)

        image_output.close()

        return True
Exemplo n.º 10
0
def write_image(image, path, bit_depth='float32', attributes=None):
    """
    Writes given image using *OpenImageIO*.

    Parameters
    ----------
    image : array_like
        Image data.
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Image bit_depth.
    attributes : array_like, optional
        An array of :class:`colour.io.ImageAttribute_Specification` class
        instances used to set attributes of the image.

    Returns
    -------
    bool
        Definition success.

    Examples
    --------
    Basic image writing:

    >>> import os
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    >>> path = os.path.join('tests', 'resources', 'CMSTestPattern.tif')
    >>> write_image(image, path)  # doctest: +SKIP
    True

    Advanced image writing while setting attributes:

    >>> compression = ImageAttribute_Specification('Compression', 'none')
    >>> write_image(image, path, 'uint8', [compression])  # doctest: +SKIP
    True
    """

    if is_openimageio_installed(raise_exception=True):
        from OpenImageIO import ImageOutput, ImageOutputOpenMode, ImageSpec

        path = str(path)

        if attributes is None:
            attributes = []

        bit_depth_specification = BIT_DEPTH_MAPPING[bit_depth]
        bit_depth = bit_depth_specification.openimageio

        image = as_float_array(image)
        image *= bit_depth_specification.domain
        if bit_depth_specification.clip:
            image = np.clip(image, 0, bit_depth_specification.domain)
        image = image.astype(bit_depth_specification.numpy)

        if image.ndim == 2:
            height, width = image.shape
            channels = 1
        else:
            height, width, channels = image.shape

        specification = ImageSpec(width, height, channels, bit_depth)
        for attribute in attributes:
            name = str(attribute.name)
            value = (str(attribute.value) if isinstance(
                attribute.value, string_types) else attribute.value)
            type_ = attribute.type_
            if attribute.type_ is None:
                specification.attribute(name, value)
            else:
                specification.attribute(name, type_, value)

        image_output = ImageOutput.create(path)
        image_output.open(path, specification, ImageOutputOpenMode.Create)
        image_output.write_image(bit_depth, image.tostring())
        image_output.close()

        return True
Exemplo n.º 11
0
        Attribute value.
    type_ : TypeDesc, optional
        Attribute type as an *OpenImageIO* :class:`TypeDesc` class instance.
    """

    def __new__(cls, name, value, type_=None):
        """
        Returns a new instance of the
        :class:`colour.ImageAttribute_Specification` class.
        """

        return super(ImageAttribute_Specification, cls).__new__(
            cls, name, value, type_)


if is_openimageio_installed():
    from OpenImageIO import UINT8, UINT16, HALF, FLOAT

    BIT_DEPTH_MAPPING = CaseInsensitiveMapping({
        'uint8':
            BitDepth_Specification('uint8', np.uint8, UINT8, 255, True),
        'uint16':
            BitDepth_Specification('uint16', np.uint16, UINT16, 65535, True),
        'float16':
            BitDepth_Specification('float16', np.float16, HALF, 1, False),
        'float32':
            BitDepth_Specification('float32', np.float32, FLOAT, 1, False)
    })
else:
    BIT_DEPTH_MAPPING = CaseInsensitiveMapping({
        'uint8':
Exemplo n.º 12
0
def read_image(
    path: str,
    bit_depth: Literal[
        "uint8", "uint16", "float16", "float32", "float64", "float128"
    ] = "float32",
    method: Union[Literal["Imageio", "OpenImageIO"], str] = "OpenImageIO",
    **kwargs: Any,
) -> NDArray:  # noqa: D405,D407,D410,D411,D414
    """
    Read the image at given path using given method.

    Parameters
    ----------
    path
        Image path.
    bit_depth
        Returned image bit depth, for the *Imageio* method, the image data is
        converted with :func:`colour.io.convert_bit_depth` definition after
        reading the image, for the *OpenImageIO* method, the bit depth
        conversion behaviour is driven directly by the library, this definition
        only converts to the relevant data type after reading.
    method
        Read method, i.e. the image library used for reading images.

    Other Parameters
    ----------------
    attributes
        {:func:`colour.io.read_image_OpenImageIO`},
        Whether to return the image attributes.

    Returns
    -------
    :class`numpy.ndarray`
        Image data.

    Notes
    -----
    -   If the given method is *OpenImageIO* but the library is not available
        writing will be performed by *Imageio*.
    -   If the given method is *Imageio*, ``kwargs`` is passed directly to the
        wrapped definition.
    -   For convenience, single channel images are squeezed to 2D arrays.

    Examples
    --------
    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)
    >>> image.shape  # doctest: +SKIP
    (1267, 1274, 3)
    >>> image.dtype
    dtype('float32')
    """

    method = validate_method(method, READ_IMAGE_METHODS)

    if method == "openimageio":  # pragma: no cover
        if not is_openimageio_installed():
            usage_warning(
                '"OpenImageIO" related API features are not available, '
                'switching to "Imageio"!'
            )
            method = "Imageio"

    function = READ_IMAGE_METHODS[method]

    if method == "openimageio":  # pragma: no cover
        kwargs = filter_kwargs(function, **kwargs)

    return function(path, bit_depth, **kwargs)
Exemplo n.º 13
0
    def test_write_image_OpenImageIO(self):  # pragma: no cover
        """Test :func:`colour.io.image.write_image_OpenImageIO` definition."""

        if not is_openimageio_installed():
            return

        from OpenImageIO import TypeDesc

        source_image_path = os.path.join(RESOURCES_DIRECTORY,
                                         "Overflowing_Gradient.png")
        target_image_path = os.path.join(self._temporary_directory,
                                         "Overflowing_Gradient.png")
        RGB = np.arange(0, 256, 1, dtype=np.uint8)[np.newaxis] * 2
        write_image_OpenImageIO(RGB, target_image_path, bit_depth="uint8")
        image = read_image_OpenImageIO(source_image_path, bit_depth="uint8")
        np.testing.assert_equal(np.squeeze(RGB), image)

        source_image_path = os.path.join(RESOURCES_DIRECTORY,
                                         "CMS_Test_Pattern.exr")
        target_image_path = os.path.join(self._temporary_directory,
                                         "CMS_Test_Pattern.exr")
        image = read_image_OpenImageIO(source_image_path)
        write_image_OpenImageIO(image, target_image_path)
        image = read_image_OpenImageIO(target_image_path)
        self.assertTupleEqual(image.shape, (1267, 1274, 3))
        self.assertIs(image.dtype, np.dtype("float32"))

        chromaticities = (
            0.73470,
            0.26530,
            0.00000,
            1.00000,
            0.00010,
            -0.07700,
            0.32168,
            0.33767,
        )
        write_attributes = [
            ImageAttribute_Specification("acesImageContainerFlag", True),
            ImageAttribute_Specification("chromaticities", chromaticities,
                                         TypeDesc("float[8]")),
            ImageAttribute_Specification("compression", "none"),
        ]
        write_image_OpenImageIO(image,
                                target_image_path,
                                attributes=write_attributes)
        image, read_attributes = read_image_OpenImageIO(target_image_path,
                                                        attributes=True)
        for write_attribute in write_attributes:
            attribute_exists = False
            for read_attribute in read_attributes:
                if write_attribute.name == read_attribute.name:
                    attribute_exists = True
                    if isinstance(write_attribute.value, tuple):
                        np.testing.assert_almost_equal(
                            write_attribute.value,
                            read_attribute.value,
                            decimal=5,
                        )
                    else:
                        self.assertEqual(write_attribute.value,
                                         read_attribute.value)

            attest(
                attribute_exists,
                f'"{write_attribute.name}" attribute was not found on image!',
            )
Exemplo n.º 14
0
__author__ = 'Colour Developers'
__copyright__ = 'Copyright (C) 2013-2016 - Colour Developers'
__license__ = 'New BSD License - http://opensource.org/licenses/BSD-3-Clause'
__maintainer__ = 'Colour Developers'
__email__ = '*****@*****.**'
__status__ = 'Production'

__all__ = [
    'BitDepth_Specification', 'BIT_DEPTH_MAPPING', 'read_image', 'write_image'
]

BitDepth_Specification = namedtuple(
    'BitDepth_Specification',
    ('name', 'numpy', 'openimageio', 'domain', 'clip'))

if is_openimageio_installed():
    from OpenImageIO import UINT8, UINT16, HALF, FLOAT

    BIT_DEPTH_MAPPING = CaseInsensitiveMapping({
        'uint8':
        BitDepth_Specification('uint8', np.uint8, UINT8, 255, True),
        'uint16':
        BitDepth_Specification('uint16', np.uint16, UINT16, 65535, True),
        'float16':
        BitDepth_Specification('float16', np.float16, HALF, 1, False),
        'float32':
        BitDepth_Specification('float32', np.float32, FLOAT, 1, False)
    })
else:
    BIT_DEPTH_MAPPING = CaseInsensitiveMapping({
        'uint8':
Exemplo n.º 15
0
def write_image(
    image: ArrayLike,
    path: str,
    bit_depth: Literal[
        "uint8", "uint16", "float16", "float32", "float64", "float128"
    ] = "float32",
    method: Union[Literal["Imageio", "OpenImageIO"], str] = "OpenImageIO",
    **kwargs: Any,
) -> Boolean:  # noqa: D405,D407,D410,D411,D414
    """
    Write given image at given path using given method.

    Parameters
    ----------
    image
        Image data.
    path
        Image path.
    bit_depth
        Bit depth to write the image at, for the *Imageio* method, the image
        data is converted with :func:`colour.io.convert_bit_depth` definition
        prior to writing the image.
    method
        Write method, i.e. the image library used for writing images.

    Other Parameters
    ----------------
    attributes
        {:func:`colour.io.write_image_OpenImageIO`},
        An array of :class:`colour.io.ImageAttribute_Specification` class
        instances used to set attributes of the image.

    Returns
    -------
    :class:`bool`
        Definition success.

    Notes
    -----
    -   If the given method is *OpenImageIO* but the library is not available
        writing will be performed by *Imageio*.
    -   If the given method is *Imageio*, ``kwargs`` is passed directly to the
        wrapped definition.

    Examples
    --------
    Basic image writing:

    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMSTestPattern.tif')
    >>> write_image(image, path)  # doctest: +SKIP
    True

    Advanced image writing while setting attributes using *OpenImageIO*:

    >>> compression = ImageAttribute_Specification('Compression', 'none')
    >>> write_image(image, path, bit_depth='uint8', attributes=[compression])
    ... # doctest: +SKIP
    True
    """

    method = validate_method(method, WRITE_IMAGE_METHODS)

    if method == "openimageio":  # pragma: no cover
        if not is_openimageio_installed():
            usage_warning(
                '"OpenImageIO" related API features are not available, '
                'switching to "Imageio"!'
            )
            method = "Imageio"

    function = WRITE_IMAGE_METHODS[method]

    if method == "openimageio":  # pragma: no cover
        kwargs = filter_kwargs(function, **kwargs)

    return function(image, path, bit_depth, **kwargs)
Exemplo n.º 16
0
Arquivo: image.py Projeto: yixw/colour
def write_image(image,
                path,
                bit_depth='float32',
                method='OpenImageIO',
                **kwargs):
    """
    Writes given image at given path using given method.

    Parameters
    ----------
    image : array_like
        Image data.
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Bit depth to write the image at, for the *Imageio* method, the image
        data is converted with :func:`colour.io.convert_bit_depth` definition
        prior to writing the image.
    method : unicode, optional
        **{'OpenImageIO', 'Imageio'}**,
        Write method, i.e. the image library used for writing images.

    Other Parameters
    ----------------
    attributes : array_like, optional
        {:func:`colour.io.write_image_OpenImageIO`},
        An array of :class:`colour.io.ImageAttribute_Specification` class
        instances used to set attributes of the image.

    Returns
    -------
    bool
        Definition success.

    Notes
    -----
    -   If the given method is *OpenImageIO* but the library is not available
        writing will be performed by *Imageio*.
    -   If the given method is *Imageio*, ``kwargs`` is passed directly to the
        wrapped definition.

    Examples
    --------
    Basic image writing:

    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMSTestPattern.tif')
    >>> write_image(image, path)  # doctest: +SKIP
    True

    Advanced image writing while setting attributes using *OpenImageIO*:

    >>> compression = ImageAttribute_Specification('Compression', 'none')
    >>> write_image(image, path, bit_depth='uint8', attributes=[compression])
    ... # doctest: +SKIP
    True
    """

    if method.lower() == 'openimageio':  # pragma: no cover
        if not is_openimageio_installed():
            usage_warning(
                '"OpenImageIO" related API features are not available, '
                'switching to "Imageio"!')
            method = 'Imageio'

    function = WRITE_IMAGE_METHODS[method]

    if method.lower() == 'openimageio':  # pragma: no cover
        kwargs = filter_kwargs(function, **kwargs)

    return function(image, path, bit_depth, **kwargs)
Exemplo n.º 17
0
Arquivo: image.py Projeto: yixw/colour
        Attribute value.
    type_ : TypeDesc, optional
        Attribute type as an *OpenImageIO* :class:`TypeDesc` class instance.
    """

    def __new__(cls, name, value, type_=None):
        """
        Returns a new instance of the
        :class:`colour.ImageAttribute_Specification` class.
        """

        return super(ImageAttribute_Specification, cls).__new__(
            cls, name, value, type_)


if is_openimageio_installed():  # pragma: no cover
    from OpenImageIO import UINT8, UINT16, HALF, FLOAT

    BIT_DEPTH_MAPPING = CaseInsensitiveMapping({
        'uint8':
            BitDepth_Specification('uint8', np.uint8, UINT8, 255, True),
        'uint16':
            BitDepth_Specification('uint16', np.uint16, UINT16, 65535, True),
        'float16':
            BitDepth_Specification('float16', np.float16, HALF, 1, False),
        'float32':
            BitDepth_Specification('float32', np.float32, FLOAT, 1, False),
        'float64':
            BitDepth_Specification('float64', np.float64, FLOAT, 1, False),
    })
    if platform.system() not in ('Windows', 'Microsoft'):  # pragma: no cover
Exemplo n.º 18
0
Arquivo: image.py Projeto: yixw/colour
def read_image(path, bit_depth='float32', method='OpenImageIO', **kwargs):
    """
    Reads the image at given path using given method.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Returned image bit depth, for the *Imageio* method, the image data is
        converted with :func:`colour.io.convert_bit_depth` definition after
        reading the image, for the *OpenImageIO* method, the bit depth
        conversion behaviour is driven directly by the library, this definition
        only converts to the relevant data type after reading.
    method : unicode, optional
        **{'OpenImageIO', 'Imageio'}**,
        Read method, i.e. the image library used for reading images.

    Other Parameters
    ----------------
    attributes : bool, optional
        {:func:`colour.io.read_image_OpenImageIO`},
        Whether to return the image attributes.

    Returns
    -------
    ndarray
        Image as a ndarray.

    Notes
    -----
    -   If the given method is *OpenImageIO* but the library is not available
        writing will be performed by *Imageio*.
    -   If the given method is *Imageio*, ``kwargs`` is passed directly to the
        wrapped definition.
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)
    >>> image.shape  # doctest: +SKIP
    (1267, 1274, 3)
    >>> image.dtype
    dtype('float32')
    """

    if method.lower() == 'openimageio':  # pragma: no cover
        if not is_openimageio_installed():
            usage_warning(
                '"OpenImageIO" related API features are not available, '
                'switching to "Imageio"!')
            method = 'Imageio'

    function = READ_IMAGE_METHODS[method]

    if method.lower() == 'openimageio':  # pragma: no cover
        kwargs = filter_kwargs(function, **kwargs)

    return function(path, bit_depth, **kwargs)
Exemplo n.º 19
0
Arquivo: image.py Projeto: yixw/colour
def read_image_OpenImageIO(path, bit_depth='float32', attributes=False):
    """
    Reads the image at given path using *OpenImageIO*.

    Parameters
    ----------
    path : unicode
        Image path.
    bit_depth : unicode, optional
        **{'float32', 'uint8', 'uint16', 'float16'}**,
        Returned image bit depth, the bit depth conversion behaviour is driven
        directly by *OpenImageIO*, this definition only converts to the
        relevant data type after reading.
    attributes : bool, optional
        Whether to return the image attributes.

    Returns
    -------
    ndarray or tuple
        Image as a ndarray or tuple of image as ndarray and list of attributes

    Notes
    -----
    -   For convenience, single channel images are squeezed to 2d arrays.

    Examples
    --------
    >>> import os
    >>> import colour
    >>> path = os.path.join(colour.__path__[0], 'io', 'tests', 'resources',
    ...                     'CMS_Test_Pattern.exr')
    >>> image = read_image(path)  # doctest: +SKIP
    """

    if is_openimageio_installed(raise_exception=True):  # pragma: no cover
        from OpenImageIO import ImageInput

        path = str(path)

        bit_depth = BIT_DEPTH_MAPPING[bit_depth]

        image = ImageInput.open(path)
        specification = image.spec()

        shape = (specification.height, specification.width,
                 specification.nchannels)

        image_data = image.read_image(bit_depth.openimageio)
        image.close()
        image = np.squeeze(
            np.array(image_data, dtype=bit_depth.numpy).reshape(shape))

        if attributes:
            extra_attributes = []
            for i in range(len(specification.extra_attribs)):
                attribute = specification.extra_attribs[i]
                extra_attributes.append(
                    ImageAttribute_Specification(
                        attribute.name, attribute.value, attribute.type))

            return image, extra_attributes
        else:
            return image