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.
Files changed (52) hide show
  1. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/PKG-INFO +1 -3
  2. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__init__.pyi +42 -42
  3. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__main__.py +2 -2
  4. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/_typing.py +6 -6
  5. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/_version.py +3 -3
  6. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/__init__.pyi +44 -44
  7. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/colorconv.py +79 -55
  8. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/colorconv.pyi +63 -56
  9. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/core.py +122 -103
  10. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/core.pyi +33 -33
  11. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/palette.py +20 -20
  12. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/palette.pyi +2 -2
  13. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/__init__.py +8 -8
  14. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/__init__.pyi +8 -8
  15. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/_fetchers.py +3 -3
  16. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/userfont.py +2 -2
  17. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/userfont.pyi +1 -1
  18. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/demo.py +41 -41
  19. chromatic_python-0.7.2/chromatic/image/__init__.pyi +66 -0
  20. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/_array.py +88 -145
  21. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/_curses.py +15 -15
  22. chromatic_python-0.7.2/chromatic/image/_glyph.py +95 -0
  23. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/PKG-INFO +1 -3
  24. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/requires.txt +0 -2
  25. chromatic_python-0.7.2/chromatic_python.egg-info/scm_version.json +8 -0
  26. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/pyproject.toml +0 -3
  27. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/tests/test_color_str.py +42 -42
  28. chromatic_python-0.7.0/chromatic/image/__init__.pyi +0 -68
  29. chromatic_python-0.7.0/chromatic/image/_glyph.py +0 -92
  30. chromatic_python-0.7.0/chromatic_python.egg-info/scm_version.json +0 -8
  31. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.gitattributes +0 -0
  32. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.github/dependabot.yml +0 -0
  33. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.github/workflows/release.yml +0 -0
  34. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/.gitignore +0 -0
  35. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/README.md +0 -0
  36. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/banner.png +0 -0
  37. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/__init__.py +0 -0
  38. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/color/__init__.py +0 -0
  39. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/fonts/userfont.schema.json +0 -0
  40. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/fonts/vga437.ttf +0 -0
  41. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/butterfly.jpg +0 -0
  42. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/escher.png +0 -0
  43. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/goblin_virus.png +0 -0
  44. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/data/images/registry.json +0 -0
  45. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic/image/__init__.py +0 -0
  46. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/SOURCES.txt +0 -0
  47. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/dependency_links.txt +0 -0
  48. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/entry_points.txt +0 -0
  49. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/scm_file_list.json +0 -0
  50. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/chromatic_python.egg-info/top_level.txt +0 -0
  51. {chromatic_python-0.7.0 → chromatic_python-0.7.2}/setup.cfg +0 -0
  52. {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.0
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
- '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',
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 map("".join, ansi_array)
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, ansi_array=ansi_array)
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['fg', 'bg']
42
- Ansi4BitAlias = L['4b', 1]
43
- Ansi8BitAlias = L['8b', 2]
44
- Ansi24BitAlias = L['24b', 3]
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 = '', obj_repr=False):
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
- (', ' if n_expected > 2 else ' ')
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.0'
22
- __version_tuple__ = version_tuple = (0, 7, 0)
21
+ __version__ = version = '0.7.2'
22
+ __version_tuple__ = version_tuple = (0, 7, 2)
23
23
 
24
- __commit_id__ = commit_id = 'g029be355a'
24
+ __commit_id__ = commit_id = 'g7703f67b1'
@@ -1,48 +1,48 @@
1
1
  __all__ = [
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',
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
- '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',
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 = ''.join(c * 2 for c in 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
- if is_3tuple := (rgb.__class__ is tuple and len(rgb) == 3):
310
- r, g, b = (min(x >> 3, 32) for x in rgb)
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.atleast_1d(value).astype(np.uint8)
326
- out = np.empty((*arr.shape, 3), dtype=np.uint8)
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
- if np.any(ansi_16c := arr < 16):
329
- out[ansi_16c] = np.take(ANSI_4BIT_RGB, arr[ansi_16c], axis=0)
330
- mask &= ~ansi_16c
331
- if np.any(colorcube := (arr >= 16) & (arr < 232)):
332
- c = arr[colorcube] - 16
333
- out[colorcube, 0] = (c // 36) * 51
334
- out[colorcube, 1] = (c % 36 // 6) * 51
335
- out[colorcube, 2] = (c % 6) * 51
336
- mask &= ~colorcube
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 tuple(out[0].tolist()) if np.isscalar(value) else out
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
- if np.any(grey := (arr[..., 1:] == arr[..., 0:1]).all(axis=-1)):
347
- c = arr[..., 0]
348
- r_lo = grey & (c < 8)
349
- r_hi = grey & (c > 248)
350
- mid = grey & ~(r_lo | r_hi)
351
- out[r_lo] = 16
352
- out[r_hi] = 231
353
- out[mid] = np.rint((c[mid] - 8) / 247 * 24) + 232
354
- mask &= ~grey
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.item() if is_3tuple else out
382
+ return out
@@ -1,32 +1,33 @@
1
1
  __all__ = [
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',
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.integer], /
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.integer], /
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.integer], /
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.integer], /
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.integer], /
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.integer], /
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.integer], /
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.integer], /
182
+ rgb: np.typing.NDArray[np.number], /
176
183
  ) -> np.typing.NDArray[np.uint8]: ...