chromatic-python 0.7.0__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/PKG-INFO +1 -3
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__init__.pyi +42 -42
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__main__.py +2 -2
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/_typing.py +6 -6
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/_version.py +3 -3
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/__init__.pyi +44 -44
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/colorconv.py +79 -55
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/colorconv.pyi +63 -56
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/core.py +122 -103
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/core.pyi +33 -33
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/palette.py +20 -20
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/palette.pyi +2 -2
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/__init__.py +8 -8
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/__init__.pyi +8 -8
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/_fetchers.py +3 -3
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/userfont.py +2 -2
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/userfont.pyi +1 -1
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/demo.py +41 -41
- chromatic_python-0.7.2/chromatic/image/__init__.pyi +66 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/_array.py +88 -145
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/_curses.py +15 -15
- chromatic_python-0.7.2/chromatic/image/_glyph.py +95 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/PKG-INFO +1 -3
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/requires.txt +0 -2
- chromatic_python-0.7.2/chromatic_python.egg-info/scm_version.json +8 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/pyproject.toml +0 -3
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/tests/test_color_str.py +42 -42
- chromatic_python-0.7.0/chromatic/image/__init__.pyi +0 -68
- chromatic_python-0.7.0/chromatic/image/_glyph.py +0 -92
- chromatic_python-0.7.0/chromatic_python.egg-info/scm_version.json +0 -8
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.gitattributes +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.github/dependabot.yml +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.github/workflows/release.yml +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.gitignore +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/README.md +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/banner.png +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__init__.py +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/__init__.py +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/fonts/userfont.schema.json +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/fonts/vga437.ttf +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/butterfly.jpg +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/escher.png +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/goblin_virus.png +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/registry.json +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/__init__.py +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/SOURCES.txt +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/dependency_links.txt +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/entry_points.txt +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/scm_file_list.json +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/top_level.txt +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/setup.cfg +0 -0
- {chromatic_python-0.7.0 → chromatic_python-0.7.2}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chromatic-python
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: ANSI art image processing and colored terminal text
|
|
5
5
|
Author: crypt0lith
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,8 +19,6 @@ Requires-Dist: numpy<2.6,>=1.25.2
|
|
|
19
19
|
Requires-Dist: pillow>=12.2.0
|
|
20
20
|
Requires-Dist: scipy<2.0,>=1.11.4
|
|
21
21
|
Requires-Dist: opencv-python
|
|
22
|
-
Requires-Dist: scikit-image
|
|
23
|
-
Requires-Dist: scikit-learn
|
|
24
22
|
Requires-Dist: fonttools>=4.60.2
|
|
25
23
|
Requires-Dist: lazy_loader
|
|
26
24
|
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
__all__ = [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
2
|
+
"Back",
|
|
3
|
+
"Color",
|
|
4
|
+
"ColorNamespace",
|
|
5
|
+
"ColorStr",
|
|
6
|
+
"Fore",
|
|
7
|
+
"SgrParameter",
|
|
8
|
+
"Style",
|
|
9
|
+
"UserFont",
|
|
10
|
+
"ansi2img",
|
|
11
|
+
"ansi_quantize",
|
|
12
|
+
"ansicolor24Bit",
|
|
13
|
+
"ansicolor4Bit",
|
|
14
|
+
"ansicolor8Bit",
|
|
15
|
+
"ansify",
|
|
16
|
+
"ascii2img",
|
|
17
|
+
"ascii_printable",
|
|
18
|
+
"color",
|
|
19
|
+
"color_chain",
|
|
20
|
+
"colorbytes",
|
|
21
|
+
"contrast_stretch",
|
|
22
|
+
"cp437_printable",
|
|
23
|
+
"data",
|
|
24
|
+
"equalize_white_point",
|
|
25
|
+
"get_font_key",
|
|
26
|
+
"get_font_object",
|
|
27
|
+
"get_glyph_masks",
|
|
28
|
+
"hexstr2rgb",
|
|
29
|
+
"image",
|
|
30
|
+
"img2ansi",
|
|
31
|
+
"img2ascii",
|
|
32
|
+
"int2rgb",
|
|
33
|
+
"named_color",
|
|
34
|
+
"read_ans",
|
|
35
|
+
"register_userfont",
|
|
36
|
+
"render_ans",
|
|
37
|
+
"reshape_ansi",
|
|
38
|
+
"rgb2hexstr",
|
|
39
|
+
"rgb2int",
|
|
40
|
+
"sort_glyphs",
|
|
41
|
+
"ttf_extract_codepoints",
|
|
42
|
+
"userfonts",
|
|
43
|
+
"set_default_ansi",
|
|
44
44
|
]
|
|
45
45
|
from . import color, data, image
|
|
46
46
|
from ._version import version as __version__
|
|
@@ -514,10 +514,10 @@ def handle_image(ns):
|
|
|
514
514
|
ansi_array = _call_from_ns(img2ansi, ns)
|
|
515
515
|
if hasattr(ns, "dumpfile"):
|
|
516
516
|
ns.dumpfile.writelines(
|
|
517
|
-
f"{s}\n".encode() for s in
|
|
517
|
+
f"{s}\n".encode() for s in ansi_array.splitlines()
|
|
518
518
|
)
|
|
519
519
|
ns.dumpfile.write(b"\x1b[0m")
|
|
520
|
-
img = _call_from_ns(ansi2img, ns,
|
|
520
|
+
img = _call_from_ns(ansi2img, ns, arr=ansi_array)
|
|
521
521
|
try:
|
|
522
522
|
outpath = ns.outfile_callback(ns, img)
|
|
523
523
|
except Exception as e:
|
|
@@ -38,21 +38,21 @@ RGBPixel: tp.TypeAlias = ShapedNDArray[tuple[L[3]], np.uint8]
|
|
|
38
38
|
|
|
39
39
|
RGBImageLike: tp.TypeAlias = Image | RGBArray
|
|
40
40
|
RGBVectorLike: tp.TypeAlias = IntSequence | RGBPixel
|
|
41
|
-
ColorDictKeys = L[
|
|
42
|
-
Ansi4BitAlias = L[
|
|
43
|
-
Ansi8BitAlias = L[
|
|
44
|
-
Ansi24BitAlias = L[
|
|
41
|
+
ColorDictKeys = L["fg", "bg"]
|
|
42
|
+
Ansi4BitAlias = L["4b", 1]
|
|
43
|
+
Ansi8BitAlias = L["8b", 2]
|
|
44
|
+
Ansi24BitAlias = L["24b", 3]
|
|
45
45
|
AnsiColorAlias = Ansi4BitAlias | Ansi8BitAlias | Ansi24BitAlias
|
|
46
46
|
FontArgType: tp.TypeAlias = tp.Union[FreeTypeFont, "UserFont", str]
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
def type_error_msg(err_obj, *expected, context: str =
|
|
49
|
+
def type_error_msg(err_obj, *expected, context: str = "", obj_repr=False):
|
|
50
50
|
n_expected = len(expected)
|
|
51
51
|
name_slots = ["{%d.__name__!r}" % n for n in range(n_expected)]
|
|
52
52
|
if n_expected > 1:
|
|
53
53
|
name_slots[-1] = f"or {name_slots[-1]}"
|
|
54
54
|
names = (
|
|
55
|
-
(
|
|
55
|
+
(", " if n_expected > 2 else " ")
|
|
56
56
|
.join([context.strip(), *name_slots])
|
|
57
57
|
.format(*expected)
|
|
58
58
|
)
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.7.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 7,
|
|
21
|
+
__version__ = version = '0.7.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 7, 2)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g7703f67b1'
|
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
__all__ = [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
2
|
+
"ANSI_4BIT_RGB",
|
|
3
|
+
"Back",
|
|
4
|
+
"CSI",
|
|
5
|
+
"Color",
|
|
6
|
+
"ColorNamespace",
|
|
7
|
+
"ColorStr",
|
|
8
|
+
"DEFAULT_ANSI",
|
|
9
|
+
"Fore",
|
|
10
|
+
"SGR_RESET",
|
|
11
|
+
"SgrParameter",
|
|
12
|
+
"SgrSequence",
|
|
13
|
+
"Style",
|
|
14
|
+
"ansi_4bit_to_rgb",
|
|
15
|
+
"ansi_8bit_to_rgb",
|
|
16
|
+
"ansicolor24Bit",
|
|
17
|
+
"ansicolor4Bit",
|
|
18
|
+
"ansicolor8Bit",
|
|
19
|
+
"color_chain",
|
|
20
|
+
"colorbytes",
|
|
21
|
+
"get_ansi_type",
|
|
22
|
+
"hexstr2rgb",
|
|
23
|
+
"hsl2rgb",
|
|
24
|
+
"hsv2rgb",
|
|
25
|
+
"int2rgb",
|
|
26
|
+
"is_u24",
|
|
27
|
+
"lab2rgb",
|
|
28
|
+
"lab2xyz",
|
|
29
|
+
"named_color",
|
|
30
|
+
"nearest_ansi_4bit_rgb",
|
|
31
|
+
"nearest_ansi_8bit_rgb",
|
|
32
|
+
"randcolor",
|
|
33
|
+
"rgb2ansi_escape",
|
|
34
|
+
"rgb2hexstr",
|
|
35
|
+
"rgb2hsl",
|
|
36
|
+
"rgb2hsv",
|
|
37
|
+
"rgb2int",
|
|
38
|
+
"rgb2lab",
|
|
39
|
+
"rgb2xyz",
|
|
40
|
+
"rgb_diff",
|
|
41
|
+
"rgb_dispatch",
|
|
42
|
+
"rgb_to_ansi_8bit",
|
|
43
|
+
"set_default_ansi",
|
|
44
|
+
"xyz2lab",
|
|
45
|
+
"xyz2rgb",
|
|
46
46
|
]
|
|
47
47
|
from . import colorconv, core, palette
|
|
48
48
|
from .colorconv import (
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
__all__ = [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
"ANSI_4BIT_RGB",
|
|
3
|
+
"ansi_4bit_to_rgb",
|
|
4
|
+
"ansi_8bit_to_rgb",
|
|
5
|
+
"int2rgb",
|
|
6
|
+
"hexstr2rgb",
|
|
7
|
+
"hsl2rgb",
|
|
8
|
+
"hsv2rgb",
|
|
9
|
+
"is_u24",
|
|
10
|
+
"lab2rgb",
|
|
11
|
+
"lab2xyz",
|
|
12
|
+
"nearest_ansi_4bit_rgb",
|
|
13
|
+
"nearest_ansi_8bit_rgb",
|
|
14
|
+
"rgb2int",
|
|
15
|
+
"rgb2hexstr",
|
|
16
|
+
"rgb2hsl",
|
|
17
|
+
"rgb2hsv",
|
|
18
|
+
"rgb2lab",
|
|
19
|
+
"rgb2xyz",
|
|
20
|
+
"rgb_diff",
|
|
21
|
+
"rgb_to_ansi_8bit",
|
|
22
|
+
"xyz2lab",
|
|
23
|
+
"xyz2rgb",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
import typing as tp
|
|
@@ -68,7 +68,7 @@ def hexstr2rgb(s: str, /) -> Int3Tuple:
|
|
|
68
68
|
n //= 4
|
|
69
69
|
s = s[:n]
|
|
70
70
|
if n == 3: # rgb -> rrggbb
|
|
71
|
-
s =
|
|
71
|
+
s = "".join(c * 2 for c in s)
|
|
72
72
|
x = int(s, 16)
|
|
73
73
|
if not 0 <= x < (1 << 24):
|
|
74
74
|
raise ValueError(f"{x:#x} is not u24")
|
|
@@ -306,53 +306,77 @@ ANSI_4BIT_RGB_LUT = _4b_lookup()
|
|
|
306
306
|
|
|
307
307
|
|
|
308
308
|
def nearest_ansi_4bit_rgb(rgb, /):
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
else
|
|
312
|
-
arr = np.asarray(rgb, dtype=np.uint8) >> 3
|
|
313
|
-
if not arr.shape or arr.shape[-1] != 3:
|
|
314
|
-
raise ValueError
|
|
315
|
-
r, g, b = arr[..., 0], arr[..., 1], arr[..., 2]
|
|
316
|
-
out = ANSI_4BIT_RGB_LUT[r, g, b]
|
|
317
|
-
return tuple(out.tolist()) if is_3tuple else out
|
|
309
|
+
arr = np.asarray(rgb, dtype=np.uint8) >> 3
|
|
310
|
+
out = ANSI_4BIT_RGB_LUT[arr[..., 0], arr[..., 1], arr[..., 2]]
|
|
311
|
+
return tuple(out.tolist()) if arr.shape == (3,) else out
|
|
318
312
|
|
|
319
313
|
|
|
320
314
|
def nearest_ansi_8bit_rgb(value, /):
|
|
321
315
|
return ansi_8bit_to_rgb(rgb_to_ansi_8bit(value))
|
|
322
316
|
|
|
323
317
|
|
|
318
|
+
def _ansi_8bit_to_rgb_fast(value: int, /):
|
|
319
|
+
if value < 16:
|
|
320
|
+
return ANSI_4BIT_RGB[value]
|
|
321
|
+
elif value < 232:
|
|
322
|
+
value -= 16
|
|
323
|
+
return value // 36 * 51, (value % 36 // 6) * 51, (value % 6) * 51
|
|
324
|
+
else:
|
|
325
|
+
return (8 + (value - 232) * 10,) * 3
|
|
326
|
+
|
|
327
|
+
|
|
324
328
|
def ansi_8bit_to_rgb(value, /):
|
|
325
|
-
arr = np.
|
|
326
|
-
|
|
329
|
+
arr = np.asarray(value, dtype=np.uint8)
|
|
330
|
+
if arr.ndim == 0:
|
|
331
|
+
return _ansi_8bit_to_rgb_fast(arr.item())
|
|
332
|
+
out = np.empty(arr.shape + (3,), dtype=np.uint8)
|
|
327
333
|
mask = np.ones(arr.shape, dtype=np.bool_)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
334
|
+
ansi_16c = arr < 16
|
|
335
|
+
out[ansi_16c] = np.take(ANSI_4BIT_RGB, arr[ansi_16c], axis=0)
|
|
336
|
+
mask &= ~ansi_16c
|
|
337
|
+
colorcube = (arr >= 16) & (arr < 232)
|
|
338
|
+
c = arr[colorcube] - 16
|
|
339
|
+
out[colorcube, 0] = c // 36
|
|
340
|
+
out[colorcube, 1] = c % 36 // 6
|
|
341
|
+
out[colorcube, 2] = c % 6
|
|
342
|
+
out[colorcube, :] *= 51
|
|
343
|
+
mask &= ~colorcube
|
|
337
344
|
out[mask] = (8 + (arr[mask] - 232) * 10)[:, None]
|
|
338
|
-
return
|
|
345
|
+
return out
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def _rgb_to_ansi_8bit_fast(r: int, g: int, b: int, /):
|
|
349
|
+
if not (r == g == b):
|
|
350
|
+
return (
|
|
351
|
+
16
|
|
352
|
+
+ (36 * round(r / 255 * 5))
|
|
353
|
+
+ (6 * round(g / 255 * 5))
|
|
354
|
+
+ round(b / 255 * 5)
|
|
355
|
+
)
|
|
356
|
+
elif r < 8:
|
|
357
|
+
return 16
|
|
358
|
+
elif r > 248:
|
|
359
|
+
return 231
|
|
360
|
+
else:
|
|
361
|
+
return round((r - 8) / 247 * 24) + 232
|
|
339
362
|
|
|
340
363
|
|
|
341
364
|
def rgb_to_ansi_8bit(rgb, /) -> int | ShapedNDArray[tuple[int, ...], np.uint8]:
|
|
342
|
-
is_3tuple = rgb.__class__ is tuple and len(rgb) == 3
|
|
343
365
|
arr = np.asarray(rgb, dtype=np.uint8)
|
|
366
|
+
if arr.shape == (3,):
|
|
367
|
+
return _rgb_to_ansi_8bit_fast(*arr.tolist())
|
|
344
368
|
out = np.zeros(arr.shape[:-1], dtype=np.uint8)
|
|
345
369
|
mask = np.ones(arr.shape[:-1], dtype=np.bool_)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
370
|
+
grey = (arr[..., 1:] == arr[..., 0:1]).all(axis=-1)
|
|
371
|
+
c = arr[..., 0]
|
|
372
|
+
r_lo = grey & (c < 8)
|
|
373
|
+
r_hi = grey & (c > 248)
|
|
374
|
+
mid = grey & ~(r_lo | r_hi)
|
|
375
|
+
out[r_lo] = 16
|
|
376
|
+
out[r_hi] = 231
|
|
377
|
+
out[mid] = np.rint((c[mid] - 8) / 247 * 24) + 232
|
|
378
|
+
mask &= ~grey
|
|
355
379
|
rest = np.rint(arr[mask] / 255 * 5)
|
|
356
380
|
r, g, b = rest[..., 0], rest[..., 1], rest[..., 2]
|
|
357
381
|
out[mask] = 16 + (36 * r) + (6 * g) + b
|
|
358
|
-
return out
|
|
382
|
+
return out
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
__all__ = [
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
2
|
+
"ANSI_4BIT_RGB",
|
|
3
|
+
"ansi_4bit_to_rgb",
|
|
4
|
+
"ansi_8bit_to_rgb",
|
|
5
|
+
"int2rgb",
|
|
6
|
+
"hexstr2rgb",
|
|
7
|
+
"hsl2rgb",
|
|
8
|
+
"hsv2rgb",
|
|
9
|
+
"is_u24",
|
|
10
|
+
"lab2rgb",
|
|
11
|
+
"lab2xyz",
|
|
12
|
+
"nearest_ansi_4bit_rgb",
|
|
13
|
+
"nearest_ansi_8bit_rgb",
|
|
14
|
+
"rgb2int",
|
|
15
|
+
"rgb2hexstr",
|
|
16
|
+
"rgb2hsl",
|
|
17
|
+
"rgb2hsv",
|
|
18
|
+
"rgb2lab",
|
|
19
|
+
"rgb2xyz",
|
|
20
|
+
"rgb_diff",
|
|
21
|
+
"rgb_to_ansi_8bit",
|
|
22
|
+
"xyz2lab",
|
|
23
|
+
"xyz2rgb",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
import typing as tp
|
|
27
27
|
from typing import Literal as L
|
|
28
28
|
|
|
29
29
|
import numpy as np
|
|
30
|
+
from _typeshed import ConvertibleToInt
|
|
30
31
|
|
|
31
32
|
from .._typing import Float3Tuple, Int3Tuple, RGBVectorLike, ShapedNDArray
|
|
32
33
|
|
|
@@ -49,70 +50,70 @@ def rgb2xyz[_Shape: tuple[int, ...]](
|
|
|
49
50
|
rgb: ShapedNDArray[_Shape, np.uint8], /
|
|
50
51
|
) -> ShapedNDArray[_Shape, np.float64]: ...
|
|
51
52
|
|
|
53
|
+
@tp.overload
|
|
54
|
+
def xyz2lab(xyz: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
52
55
|
@tp.overload
|
|
53
56
|
def xyz2lab[_Shape: tuple[int, ...]](
|
|
54
57
|
xyz: ShapedNDArray[_Shape, np.floating], /
|
|
55
58
|
) -> ShapedNDArray[_Shape, np.float64]: ...
|
|
56
|
-
@tp.overload
|
|
57
|
-
def xyz2lab(xyz: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
58
59
|
|
|
60
|
+
@tp.overload
|
|
61
|
+
def lab2xyz(lab: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
59
62
|
@tp.overload
|
|
60
63
|
def lab2xyz[_Shape: tuple[int, ...]](
|
|
61
64
|
lab: ShapedNDArray[_Shape, np.floating], /
|
|
62
65
|
) -> ShapedNDArray[_Shape, np.float64]: ...
|
|
63
|
-
@tp.overload
|
|
64
|
-
def lab2xyz(lab: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
65
66
|
|
|
67
|
+
@tp.overload
|
|
68
|
+
def hsl2rgb(hsl: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
66
69
|
@tp.overload
|
|
67
70
|
def hsl2rgb[_Shape: tuple[int, ...]](
|
|
68
71
|
hsl: ShapedNDArray[_Shape, np.floating], /
|
|
69
72
|
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
70
|
-
@tp.overload
|
|
71
|
-
def hsl2rgb(hsl: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
72
73
|
|
|
74
|
+
@tp.overload
|
|
75
|
+
def rgb2hsl(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float32]: ...
|
|
73
76
|
@tp.overload
|
|
74
77
|
def rgb2hsl[_Shape: tuple[int, ...]](
|
|
75
|
-
rgb: ShapedNDArray[_Shape, np.
|
|
78
|
+
rgb: ShapedNDArray[_Shape, np.number], /
|
|
76
79
|
) -> ShapedNDArray[_Shape, np.float32]: ...
|
|
77
|
-
@tp.overload
|
|
78
|
-
def rgb2hsl(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float32]: ...
|
|
79
80
|
|
|
81
|
+
@tp.overload
|
|
82
|
+
def hsv2rgb(hsv: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
80
83
|
@tp.overload
|
|
81
84
|
def hsv2rgb[_Shape: tuple[int, ...]](
|
|
82
85
|
hsv: ShapedNDArray[_Shape, np.floating], /
|
|
83
86
|
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
84
|
-
@tp.overload
|
|
85
|
-
def hsv2rgb(hsv: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
86
87
|
|
|
88
|
+
@tp.overload
|
|
89
|
+
def rgb2hsv(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float32]: ...
|
|
87
90
|
@tp.overload
|
|
88
91
|
def rgb2hsv[_Shape: tuple[int, ...]](
|
|
89
|
-
rgb: ShapedNDArray[_Shape, np.
|
|
92
|
+
rgb: ShapedNDArray[_Shape, np.number], /
|
|
90
93
|
) -> ShapedNDArray[_Shape, np.float32]: ...
|
|
91
|
-
@tp.overload
|
|
92
|
-
def rgb2hsv(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float32]: ...
|
|
93
94
|
|
|
95
|
+
@tp.overload
|
|
96
|
+
def lab2rgb(lab: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
94
97
|
@tp.overload
|
|
95
98
|
def lab2rgb[_Shape: tuple[int, ...]](
|
|
96
99
|
lab: ShapedNDArray[_Shape, np.floating], /
|
|
97
100
|
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
98
|
-
@tp.overload
|
|
99
|
-
def lab2rgb(lab: Float3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
100
101
|
|
|
102
|
+
@tp.overload
|
|
103
|
+
def rgb2lab(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
101
104
|
@tp.overload
|
|
102
105
|
def rgb2lab[_Shape: tuple[int, ...]](
|
|
103
106
|
rgb: ShapedNDArray[_Shape, np.uint8], /
|
|
104
107
|
) -> ShapedNDArray[_Shape, np.float64]: ...
|
|
105
|
-
@tp.overload
|
|
106
|
-
def rgb2lab(rgb: Int3Tuple, /) -> ShapedNDArray[tuple[L[3]], np.float64]: ...
|
|
107
108
|
|
|
108
|
-
@tp.overload
|
|
109
|
-
def rgb_diff[_Shape: tuple[int, ...]](
|
|
110
|
-
rgb1: ShapedNDArray[_Shape, np.integer], rgb2: ShapedNDArray[_Shape, np.integer], /
|
|
111
|
-
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
112
109
|
@tp.overload
|
|
113
110
|
def rgb_diff(
|
|
114
111
|
rgb1: Int3Tuple, rgb2: Int3Tuple, /
|
|
115
112
|
) -> ShapedNDArray[tuple[L[3]], np.uint8]: ...
|
|
113
|
+
@tp.overload
|
|
114
|
+
def rgb_diff[_Shape: tuple[int, ...]](
|
|
115
|
+
rgb1: ShapedNDArray[_Shape, np.number], rgb2: ShapedNDArray[_Shape, np.number], /
|
|
116
|
+
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
116
117
|
|
|
117
118
|
ANSI_4BIT_RGB: tp.Final[
|
|
118
119
|
tuple[
|
|
@@ -139,38 +140,44 @@ def ansi_4bit_to_rgb(value: int, /) -> Int3Tuple: ...
|
|
|
139
140
|
|
|
140
141
|
ANSI_4BIT_RGB_LUT: tp.Final[ShapedNDArray[tuple[L[32], L[32], L[32], L[3]], np.uint8]]
|
|
141
142
|
|
|
143
|
+
@tp.overload
|
|
144
|
+
def nearest_ansi_4bit_rgb(rgb: Int3Tuple, /) -> Int3Tuple: ...
|
|
145
|
+
@tp.overload
|
|
146
|
+
def nearest_ansi_4bit_rgb(rgb: tp.Sequence[ConvertibleToInt], /) -> Int3Tuple: ...
|
|
142
147
|
@tp.overload
|
|
143
148
|
def nearest_ansi_4bit_rgb[_Shape: tuple[int, ...]](
|
|
144
|
-
rgb: ShapedNDArray[_Shape, np.
|
|
149
|
+
rgb: ShapedNDArray[_Shape, np.number], /
|
|
145
150
|
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
146
|
-
@tp.overload
|
|
147
|
-
def nearest_ansi_4bit_rgb(rgb: Int3Tuple, /) -> Int3Tuple: ...
|
|
148
151
|
|
|
152
|
+
@tp.overload
|
|
153
|
+
def nearest_ansi_8bit_rgb(rgb: Int3Tuple, /) -> Int3Tuple: ...
|
|
154
|
+
@tp.overload
|
|
155
|
+
def nearest_ansi_8bit_rgb(rgb: tp.Sequence[ConvertibleToInt], /) -> Int3Tuple: ...
|
|
149
156
|
@tp.overload
|
|
150
157
|
def nearest_ansi_8bit_rgb[_Shape: tuple[int, ...]](
|
|
151
|
-
rgb: ShapedNDArray[_Shape, np.
|
|
158
|
+
rgb: ShapedNDArray[_Shape, np.number], /
|
|
152
159
|
) -> ShapedNDArray[_Shape, np.uint8]: ...
|
|
153
|
-
@tp.overload
|
|
154
|
-
def nearest_ansi_8bit_rgb(rgb: Int3Tuple, /) -> Int3Tuple: ...
|
|
155
160
|
|
|
161
|
+
@tp.overload
|
|
162
|
+
def ansi_8bit_to_rgb(value: int, /) -> Int3Tuple: ...
|
|
156
163
|
@tp.overload
|
|
157
164
|
def ansi_8bit_to_rgb[_Shape: tuple[int, ...]](
|
|
158
|
-
value: ShapedNDArray[_Shape, np.
|
|
165
|
+
value: ShapedNDArray[_Shape, np.number], /
|
|
159
166
|
) -> ShapedNDArray[tuple[*_Shape, L[3]], np.uint8]: ...
|
|
160
|
-
@tp.overload
|
|
161
|
-
def ansi_8bit_to_rgb(value: int, /) -> Int3Tuple: ...
|
|
162
167
|
|
|
163
168
|
@tp.overload
|
|
164
169
|
def rgb_to_ansi_8bit(rgb: Int3Tuple, /) -> int: ...
|
|
165
170
|
@tp.overload
|
|
171
|
+
def rgb_to_ansi_8bit(rgb: tp.Sequence[ConvertibleToInt], /) -> int: ...
|
|
172
|
+
@tp.overload
|
|
166
173
|
def rgb_to_ansi_8bit[_D1: int](
|
|
167
|
-
rgb: ShapedNDArray[tuple[_D1, L[3]], np.
|
|
174
|
+
rgb: ShapedNDArray[tuple[_D1, L[3]], np.number], /
|
|
168
175
|
) -> ShapedNDArray[tuple[_D1], np.uint8]: ...
|
|
169
176
|
@tp.overload
|
|
170
177
|
def rgb_to_ansi_8bit[_D1: int, _D2: int](
|
|
171
|
-
rgb: ShapedNDArray[tuple[_D1, _D2, L[3]], np.
|
|
178
|
+
rgb: ShapedNDArray[tuple[_D1, _D2, L[3]], np.number], /
|
|
172
179
|
) -> ShapedNDArray[tuple[_D1, _D2], np.uint8]: ...
|
|
173
180
|
@tp.overload
|
|
174
181
|
def rgb_to_ansi_8bit(
|
|
175
|
-
rgb: np.typing.NDArray[np.
|
|
182
|
+
rgb: np.typing.NDArray[np.number], /
|
|
176
183
|
) -> np.typing.NDArray[np.uint8]: ...
|