跳到内容

颜色

颜色定义按照 CSS3 CSS 颜色模块级别 3 规范使用。

一些颜色有多个名称指向相同的颜色,例如 grey 和 gray 或 aqua 和 cyan。

在这些情况下,按字母顺序排序时,最后一个颜色优先,例如 Color((0, 255, 255)).as_named() == 'cyan' 因为 “cyan” 在 “aqua” 之后。

RGBA

RGBA(r: float, g: float, b: float, alpha: float | None)

仅供内部使用,作为颜色的表示。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
35
36
37
38
39
40
41
def __init__(self, r: float, g: float, b: float, alpha: float | None):
    self.r = r
    self.g = g
    self.b = b
    self.alpha = alpha

    self._tuple: tuple[float, float, float, float | None] = (r, g, b, alpha)

Color

Color(value: ColorType)

基类: Representation

表示一种颜色。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def __init__(self, value: ColorType) -> None:
    self._rgba: RGBA
    self._original: ColorType
    if isinstance(value, (tuple, list)):
        self._rgba = parse_tuple(value)
    elif isinstance(value, str):
        self._rgba = parse_str(value)
    elif isinstance(value, Color):
        self._rgba = value._rgba
        value = value._original
    else:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: value must be a tuple, list or string',
        )

    # if we've got here value must be a valid color
    self._original = value

original

original() -> ColorType

传递给 Color 的原始值。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
103
104
105
106
107
def original(self) -> ColorType:
    """
    Original value passed to `Color`.
    """
    return self._original

as_named

as_named(*, fallback: bool = False) -> str

如果能在 COLORS_BY_VALUE 字典中找到颜色名称,则返回颜色名称,否则返回颜色的十六进制表示形式或引发 ValueError

参数

名称 类型 描述 默认值
fallback bool

如果为 True,当找不到命名颜色时,回退到返回颜色的十六进制表示形式,而不是引发 ValueError。

False

返回

类型 描述
str

颜色名称,或颜色的十六进制表示形式。

引发

类型 描述
ValueError

当找不到命名颜色且 fallback 为 False 时。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def as_named(self, *, fallback: bool = False) -> str:
    """
    Returns the name of the color if it can be found in `COLORS_BY_VALUE` dictionary,
    otherwise returns the hexadecimal representation of the color or raises `ValueError`.

    Args:
        fallback: If True, falls back to returning the hexadecimal representation of
            the color instead of raising a ValueError when no named color is found.

    Returns:
        The name of the color, or the hexadecimal representation of the color.

    Raises:
        ValueError: When no named color is found and fallback is `False`.
    """
    if self._rgba.alpha is not None:
        return self.as_hex()
    rgb = cast(Tuple[int, int, int], self.as_rgb_tuple())

    if rgb in COLORS_BY_VALUE:
        return COLORS_BY_VALUE[rgb]
    else:
        if fallback:
            return self.as_hex()
        else:
            raise ValueError('no named color found, use fallback=True, as_hex() or as_rgb()')

as_hex

as_hex(format: Literal['short', 'long'] = 'short') -> str

返回颜色的十六进制表示形式。

表示颜色的十六进制字符串可以是 3、4、6 或 8 个字符,具体取决于是否可以使用颜色的“短”表示形式以及是否存在 alpha 通道。

返回

类型 描述
str

颜色的十六进制表示形式。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def as_hex(self, format: Literal['short', 'long'] = 'short') -> str:
    """Returns the hexadecimal representation of the color.

    Hex string representing the color can be 3, 4, 6, or 8 characters depending on whether the string
    a "short" representation of the color is possible and whether there's an alpha channel.

    Returns:
        The hexadecimal representation of the color.
    """
    values = [float_to_255(c) for c in self._rgba[:3]]
    if self._rgba.alpha is not None:
        values.append(float_to_255(self._rgba.alpha))

    as_hex = ''.join(f'{v:02x}' for v in values)
    if format == 'short' and all(c in repeat_colors for c in values):
        as_hex = ''.join(as_hex[c] for c in range(0, len(as_hex), 2))
    return f'#{as_hex}'

as_rgb

as_rgb() -> str

颜色为 rgb(<r>, <g>, <b>)rgba(<r>, <g>, <b>, <a>) 字符串。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
154
155
156
157
158
159
160
161
162
163
164
def as_rgb(self) -> str:
    """
    Color as an `rgb(<r>, <g>, <b>)` or `rgba(<r>, <g>, <b>, <a>)` string.
    """
    if self._rgba.alpha is None:
        return f'rgb({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)})'
    else:
        return (
            f'rgba({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)}, '
            f'{round(self._alpha_float(), 2)})'
        )

as_rgb_tuple

as_rgb_tuple(*, alpha: bool | None = None) -> ColorTuple

返回颜色作为 RGB 或 RGBA 元组。

参数

名称 类型 描述 默认值
alpha bool | None

是否包含 alpha 通道。此输入有三个选项

  • None (默认): 仅当设置了 alpha 时才包含 alpha。(例如,不是 None)
  • True: 始终包含 alpha。
  • False: 始终省略 alpha。
None

返回

类型 描述
ColorTuple

一个元组,包含红色、绿色和蓝色通道的值,范围为 0 到 255。如果包含 alpha,则范围为 0 到 1。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
def as_rgb_tuple(self, *, alpha: bool | None = None) -> ColorTuple:
    """
    Returns the color as an RGB or RGBA tuple.

    Args:
        alpha: Whether to include the alpha channel. There are three options for this input:

            - `None` (default): Include alpha only if it's set. (e.g. not `None`)
            - `True`: Always include alpha.
            - `False`: Always omit alpha.

    Returns:
        A tuple that contains the values of the red, green, and blue channels in the range 0 to 255.
            If alpha is included, it is in the range 0 to 1.
    """
    r, g, b = (float_to_255(c) for c in self._rgba[:3])
    if alpha is None and self._rgba.alpha is None or alpha is not None and not alpha:
        return r, g, b
    else:
        return r, g, b, self._alpha_float()

as_hsl

as_hsl() -> str

颜色为 hsl(<h>, <s>, <l>)hsl(<h>, <s>, <l>, <a>) 字符串。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
187
188
189
190
191
192
193
194
195
196
def as_hsl(self) -> str:
    """
    Color as an `hsl(<h>, <s>, <l>)` or `hsl(<h>, <s>, <l>, <a>)` string.
    """
    if self._rgba.alpha is None:
        h, s, li = self.as_hsl_tuple(alpha=False)  # type: ignore
        return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%})'
    else:
        h, s, li, a = self.as_hsl_tuple(alpha=True)  # type: ignore
        return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%}, {round(a, 2)})'

as_hsl_tuple

as_hsl_tuple(*, alpha: bool | None = None) -> HslColorTuple

返回颜色作为 HSL 或 HSLA 元组。

参数

名称 类型 描述 默认值
alpha bool | None

是否包含 alpha 通道。

  • None (默认): 仅当设置了 alpha 通道时才包含。(例如,不是 None)。
  • True: 始终包含 alpha。
  • False: 始终省略 alpha。
None

返回

类型 描述
HslColorTuple

颜色作为色调、饱和度、亮度以及 alpha(如果包含)的元组。所有元素都在 0 到 1 的范围内。

注意

这是 HTML 和大多数其他地方使用的 HSL,而不是 Python 的 colorsys 中使用的 HLS。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
def as_hsl_tuple(self, *, alpha: bool | None = None) -> HslColorTuple:
    """
    Returns the color as an HSL or HSLA tuple.

    Args:
        alpha: Whether to include the alpha channel.

            - `None` (default): Include the alpha channel only if it's set (e.g. not `None`).
            - `True`: Always include alpha.
            - `False`: Always omit alpha.

    Returns:
        The color as a tuple of hue, saturation, lightness, and alpha (if included).
            All elements are in the range 0 to 1.

    Note:
        This is HSL as used in HTML and most other places, not HLS as used in Python's `colorsys`.
    """
    h, l, s = rgb_to_hls(self._rgba.r, self._rgba.g, self._rgba.b)
    if alpha is None:
        if self._rgba.alpha is None:
            return h, s, l
        else:
            return h, s, l, self._alpha_float()
    return (h, s, l, self._alpha_float()) if alpha else (h, s, l)

parse_tuple

parse_tuple(value: tuple[Any, ...]) -> RGBA

解析元组或列表以获取 RGBA 值。

参数

名称 类型 描述 默认值
value tuple[Any, ...]

一个元组或列表。

required

返回

类型 描述
RGBA

从输入元组解析的 RGBA 元组。

引发

类型 描述
PydanticCustomError

如果元组无效。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
def parse_tuple(value: tuple[Any, ...]) -> RGBA:
    """Parse a tuple or list to get RGBA values.

    Args:
        value: A tuple or list.

    Returns:
        An `RGBA` tuple parsed from the input tuple.

    Raises:
        PydanticCustomError: If tuple is not valid.
    """
    if len(value) == 3:
        r, g, b = (parse_color_value(v) for v in value)
        return RGBA(r, g, b, None)
    elif len(value) == 4:
        r, g, b = (parse_color_value(v) for v in value[:3])
        return RGBA(r, g, b, parse_float_alpha(value[3]))
    else:
        raise PydanticCustomError('color_error', 'value is not a valid color: tuples must have length 3 or 4')

parse_str

parse_str(value: str) -> RGBA

解析表示颜色的字符串为 RGBA 元组。

输入字符串的可能格式包括

  • 命名颜色,请参阅 COLORS_BY_NAME
  • 十六进制短格式,例如 <prefix>fff (前缀可以是 #0x 或空)
  • 十六进制长格式,例如 <prefix>ffffff (前缀可以是 #0x 或空)
  • rgb(<r>, <g>, <b>)
  • rgba(<r>, <g>, <b>, <a>)
  • transparent

参数

名称 类型 描述 默认值
value str

表示颜色的字符串。

required

返回

类型 描述
RGBA

从输入字符串解析的 RGBA 元组。

引发

类型 描述
ValueError

如果输入字符串无法解析为 RGBA 元组。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
def parse_str(value: str) -> RGBA:
    """
    Parse a string representing a color to an RGBA tuple.

    Possible formats for the input string include:

    * named color, see `COLORS_BY_NAME`
    * hex short eg. `<prefix>fff` (prefix can be `#`, `0x` or nothing)
    * hex long eg. `<prefix>ffffff` (prefix can be `#`, `0x` or nothing)
    * `rgb(<r>, <g>, <b>)`
    * `rgba(<r>, <g>, <b>, <a>)`
    * `transparent`

    Args:
        value: A string representing a color.

    Returns:
        An `RGBA` tuple parsed from the input string.

    Raises:
        ValueError: If the input string cannot be parsed to an RGBA tuple.
    """

    value_lower = value.lower()
    if value_lower in COLORS_BY_NAME:
        r, g, b = COLORS_BY_NAME[value_lower]
        return ints_to_rgba(r, g, b, None)

    m = re.fullmatch(r_hex_short, value_lower)
    if m:
        *rgb, a = m.groups()
        r, g, b = (int(v * 2, 16) for v in rgb)
        alpha = int(a * 2, 16) / 255 if a else None
        return ints_to_rgba(r, g, b, alpha)

    m = re.fullmatch(r_hex_long, value_lower)
    if m:
        *rgb, a = m.groups()
        r, g, b = (int(v, 16) for v in rgb)
        alpha = int(a, 16) / 255 if a else None
        return ints_to_rgba(r, g, b, alpha)

    m = re.fullmatch(r_rgb, value_lower) or re.fullmatch(r_rgb_v4_style, value_lower)
    if m:
        return ints_to_rgba(*m.groups())  # type: ignore

    m = re.fullmatch(r_hsl, value_lower) or re.fullmatch(r_hsl_v4_style, value_lower)
    if m:
        return parse_hsl(*m.groups())  # type: ignore

    if value_lower == 'transparent':
        return RGBA(0, 0, 0, 0)

    raise PydanticCustomError(
        'color_error',
        'value is not a valid color: string not recognised as a valid color',
    )

ints_to_rgba

ints_to_rgba(
    r: int | str,
    g: int | str,
    b: int | str,
    alpha: float | None = None,
) -> RGBA

将 RGB 颜色的整数或字符串值以及可选的 alpha 值转换为 RGBA 对象。

参数

名称 类型 描述 默认值
r int | str

表示红色值的整数或字符串。

required
g int | str

表示绿色值的整数或字符串。

required
b int | str

表示蓝色值的整数或字符串。

required
alpha float | None

表示 alpha 值的浮点数。默认为 None。

None

返回

类型 描述
RGBA

RGBA 类的实例,具有相应的颜色和 alpha 值。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
def ints_to_rgba(
    r: int | str,
    g: int | str,
    b: int | str,
    alpha: float | None = None,
) -> RGBA:
    """
    Converts integer or string values for RGB color and an optional alpha value to an `RGBA` object.

    Args:
        r: An integer or string representing the red color value.
        g: An integer or string representing the green color value.
        b: An integer or string representing the blue color value.
        alpha: A float representing the alpha value. Defaults to None.

    Returns:
        An instance of the `RGBA` class with the corresponding color and alpha values.
    """
    return RGBA(
        parse_color_value(r),
        parse_color_value(g),
        parse_color_value(b),
        parse_float_alpha(alpha),
    )

parse_color_value

parse_color_value(
    value: int | str, max_val: int = 255
) -> float

解析提供的颜色值并返回 0 到 1 之间的数字。

参数

名称 类型 描述 默认值
value int | str

整数或字符串颜色值。

required
max_val int

最大范围值。默认为 255。

255

引发

类型 描述
PydanticCustomError

如果值不是有效的颜色。

返回

类型 描述
float

0 到 1 之间的数字。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
def parse_color_value(value: int | str, max_val: int = 255) -> float:
    """
    Parse the color value provided and return a number between 0 and 1.

    Args:
        value: An integer or string color value.
        max_val: Maximum range value. Defaults to 255.

    Raises:
        PydanticCustomError: If the value is not a valid color.

    Returns:
        A number between 0 and 1.
    """
    try:
        color = float(value)
    except ValueError as e:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: color values must be a valid number',
        ) from e
    if 0 <= color <= max_val:
        return color / max_val
    else:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: color values must be in the range 0 to {max_val}',
            {'max_val': max_val},
        )

parse_float_alpha

parse_float_alpha(
    value: None | str | float | int,
) -> float | None

解析 alpha 值,检查它是否是 0 到 1 范围内的有效浮点数。

参数

名称 类型 描述 默认值
value None | str | float | int

要解析的输入值。

required

返回

类型 描述
float | None

解析后的值,如果值为 None 或等于 1,则为 None

引发

类型 描述
PydanticCustomError

如果输入值无法成功解析为预期范围内的浮点数。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
def parse_float_alpha(value: None | str | float | int) -> float | None:
    """
    Parse an alpha value checking it's a valid float in the range 0 to 1.

    Args:
        value: The input value to parse.

    Returns:
        The parsed value as a float, or `None` if the value was None or equal 1.

    Raises:
        PydanticCustomError: If the input value cannot be successfully parsed as a float in the expected range.
    """
    if value is None:
        return None
    try:
        if isinstance(value, str) and value.endswith('%'):
            alpha = float(value[:-1]) / 100
        else:
            alpha = float(value)
    except ValueError as e:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: alpha values must be a valid float',
        ) from e

    if math.isclose(alpha, 1):
        return None
    elif 0 <= alpha <= 1:
        return alpha
    else:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: alpha values must be in the range 0 to 1',
        )

parse_hsl

parse_hsl(
    h: str,
    h_units: str,
    sat: str,
    light: str,
    alpha: float | None = None,
) -> RGBA

解析原始的色调、饱和度、亮度和 alpha 值,并转换为 RGBA。

参数

名称 类型 描述 默认值
h str

色调值。

required
h_units str

色调值的单位。

required
sat str

饱和度值。

required
light str

亮度值。

required
alpha float | None

Alpha 值。

None

返回

类型 描述
RGBA

RGBA 的实例。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
def parse_hsl(h: str, h_units: str, sat: str, light: str, alpha: float | None = None) -> RGBA:
    """
    Parse raw hue, saturation, lightness, and alpha values and convert to RGBA.

    Args:
        h: The hue value.
        h_units: The unit for hue value.
        sat: The saturation value.
        light: The lightness value.
        alpha: Alpha value.

    Returns:
        An instance of `RGBA`.
    """
    s_value, l_value = parse_color_value(sat, 100), parse_color_value(light, 100)

    h_value = float(h)
    if h_units in {None, 'deg'}:
        h_value = h_value % 360 / 360
    elif h_units == 'rad':
        h_value = h_value % rads / rads
    else:
        # turns
        h_value %= 1

    r, g, b = hls_to_rgb(h_value, l_value, s_value)
    return RGBA(r, g, b, parse_float_alpha(alpha))

float_to_255

float_to_255(c: float) -> int

将 0 到 1(含)之间的浮点值转换为 0 到 255(含)之间的整数。

参数

名称 类型 描述 默认值
c float

要转换的浮点值。必须在 0 到 1 之间(含)。

required

返回

类型 描述
int

给定浮点值的整数等效值,四舍五入到最接近的整数。

源代码位于 .venv/lib/python3.12/site-packages/pydantic_extra_types/color.py
456
457
458
459
460
461
462
463
464
465
466
def float_to_255(c: float) -> int:
    """
    Converts a float value between 0 and 1 (inclusive) to an integer between 0 and 255 (inclusive).

    Args:
        c: The float value to be converted. Must be between 0 and 1 (inclusive).

    Returns:
        The integer equivalent of the given float value rounded to the nearest whole number.
    """
    return round(c * 255)