Coverage for notation/hexadecimal.py: 52%
33 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
1"""
2Hexadecimal Notation
3====================
5Define objects for converting between RGB colour values and hexadecimal
6notation.
8- :func:`colour.notation.RGB_to_HEX`
9- :func:`colour.notation.HEX_to_RGB`
10"""
12from __future__ import annotations
14import typing
16import numpy as np
18from colour.algebra import normalise_maximum
20if typing.TYPE_CHECKING:
21 from colour.hints import NDArrayStr
23from colour.hints import ( # noqa: TC001
24 ArrayLike,
25 Domain1,
26 Range1,
27)
28from colour.models import eotf_inverse_sRGB, eotf_sRGB
29from colour.utilities import (
30 as_float_array,
31 as_int_array,
32 from_range_1,
33 to_domain_1,
34 usage_warning,
35)
37__author__ = "Colour Developers"
38__copyright__ = "Copyright 2013 Colour Developers"
39__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
40__maintainer__ = "Colour Developers"
41__email__ = "colour-developers@colour-science.org"
42__status__ = "Production"
44__all__ = [
45 "RGB_to_HEX",
46 "HEX_to_RGB",
47]
50def RGB_to_HEX(RGB: Domain1) -> NDArrayStr:
51 """
52 Convert from *RGB* colourspace to hexadecimal representation.
54 Parameters
55 ----------
56 RGB
57 *RGB* colourspace array with values typically normalised to [0, 1].
59 Returns
60 -------
61 :class:`str` or :class:`numpy.array`
62 Hexadecimal representation as a string in the format '#RRGGBB'.
64 Notes
65 -----
66 +------------+-----------------------+---------------+
67 | **Domain** | **Scale - Reference** | **Scale - 1** |
68 +============+=======================+===============+
69 | ``RGB`` | 1 | 1 |
70 +------------+-----------------------+---------------+
72 Examples
73 --------
74 >>> RGB = np.array([0.66666667, 0.86666667, 1.00000000])
75 >>> RGB_to_HEX(RGB)
76 '#aaddff'
77 """
79 RGB = to_domain_1(RGB)
81 if np.any(RGB < 0):
82 usage_warning(
83 '"RGB" array contains negative values, those will be clipped, '
84 "unpredictable results may occur!"
85 )
87 RGB = as_float_array(np.clip(RGB, 0, np.inf))
89 if np.any(RGB > 1):
90 usage_warning(
91 '"RGB" array contains values over 1 and will be normalised, '
92 "unpredictable results may occur!"
93 )
95 RGB = eotf_inverse_sRGB(normalise_maximum(eotf_sRGB(RGB)))
97 to_HEX = np.vectorize("{:02x}".format)
99 HEX = to_HEX(as_int_array(RGB * 255, dtype=np.uint8)).astype(object)
101 return np.asarray("#") + HEX[..., 0] + HEX[..., 1] + HEX[..., 2]
104def HEX_to_RGB(HEX: ArrayLike) -> Range1:
105 """
106 Convert from hexadecimal representation to *RGB* colourspace.
108 Parameters
109 ----------
110 HEX
111 Hexadecimal representation as a string in the format '#RRGGBB'.
113 Returns
114 -------
115 :class:`numpy.array`
116 *RGB* colourspace array with values typically normalised to [0, 1].
118 Notes
119 -----
120 +-----------+-----------------------+---------------+
121 | **Range** | **Scale - Reference** | **Scale - 1** |
122 +===========+=======================+===============+
123 | ``RGB`` | 1 | 1 |
124 +-----------+-----------------------+---------------+
126 Examples
127 --------
128 >>> HEX = "#aaddff"
129 >>> HEX_to_RGB(HEX) # doctest: +ELLIPSIS
130 array([ 0.6666666..., 0.8666666..., 1. ])
131 """
133 HEX = np.char.lstrip(HEX, "#") # pyright: ignore
135 def to_RGB(x: list) -> list:
136 """Convert specified hexadecimal representation to *RGB*."""
138 l_x = len(x)
140 return [
141 int(x[i : i + l_x // 3], 16) # pyright: ignore
142 for i in range(0, l_x, l_x // 3)
143 ]
145 to_RGB_v = np.vectorize(to_RGB, otypes=[np.ndarray])
147 RGB = as_float_array(to_RGB_v(HEX).tolist()) / 255
149 return from_range_1(RGB)