
[](https://pypi.org/project/chromatic-python/)

[](https://pepy.tech/projects/chromatic-python)
[](https://mypy-lang.org/)
Chromatic is a library for processing and transforming ANSI escape sequences (colored terminal text).
It offers a collection of algorithms and types for a variety of use cases:
- Image-to-ASCII / Image-to-ANSI conversions.
- ANSI art rendering, with support for user-defined fonts.
- A `ColorStr` type which enables precise low-level control over ANSI-escaped strings through a convenient interface.
- [colorama](https://github.com/tartley/colorama/)-style wrappers (`Fore`, `Back`, `Style`).
- Parametrization of ANSI color bit formats, allowing arbitrary conversion between 16-color, 256-color, and true-color (RGB) colorspace on any object implementing a `colorbytes` buffer.
- Et Cetera 😲
### Usage
#### ColorStr
```python
from chromatic import ColorStr
base_str = 'hello world'
red_fg = ColorStr(base_str, 0xFF0000)
assert red_fg.base_str == base_str
assert red_fg.rgb_dict == {'fg': (0xFF, 0, 0)}
assert red_fg.ansi == b'\x1b[38;5;196m'
```
`ColorStr` can handle different signatures for `color_spec`:
```python
from chromatic import ColorStr
assert all(
ColorStr('*', cs) == ColorStr('*', 0xFF0000)
for cs in [b'\x1b[38;5;196m', b'\xff\x00\x00', (0xFF, 0, 0), {'fg': 0xFF0000}]
)
```
The ANSI color format can be given as an argument, or returned by `ColorStr.as_ansi_type()` as a new instance.
```python
from chromatic import ColorStr, ansicolor24Bit, ansicolor4Bit
truecolor = ColorStr('*', 0xFF0000, ansi_type=ansicolor24Bit)
a_16color = truecolor.as_ansi_type(ansicolor4Bit)
# each ansi color format has an alias that can be used in place of the type object
assert a_16color == truecolor.as_ansi_type('4b')
assert truecolor.ansi_format is ansicolor24Bit and truecolor.ansi == b'\x1b[38;2;255;0;0m'
assert a_16color.ansi_format is ansicolor4Bit and a_16color.ansi == b'\x1b[31m'
```
Adding and removing specific ANSI codes from the escape sequence:
```python
import chromatic as cm
boring_str = cm.ColorStr('hello world')
assert boring_str.ansi == b''
bold_str = boring_str + cm.SgrParameter.BOLD
assert bold_str.ansi == b'\x1b[1m'
# use ColorStr.update_sgr() to remove and add SGR values
unbold_str = bold_str.update_sgr(cm.SgrParameter.BOLD)
assert unbold_str == boring_str
assert bold_str == unbold_str.update_sgr(cm.SgrParameter.BOLD)
```
#### Image-to-ANSI conversion
Converting an image into an array of ANSI-escaped characters, then rendering the ANSI array as another image:
```python
from chromatic.color import ansicolor4Bit
from chromatic.ascii import ansi2img, img2ansi
from chromatic.data import UserFont, butterfly
input_img = butterfly()
font = UserFont.IBM_VGA_437_8X16
# by default, `char_set` would be sorted based on the relative weight of glyphs in the font
# but because `sort_glyphs` is set to False, `char_set` will be directly mapped to the image brightness
# | <- index 0 is the 'darkest'
char_set = r"'·,•-_→+<>ⁿ*%⌂7√Iï∞πbz£9yîU{}1αHSw♥æ?GX╕╒éà⌡MF╝╩ΘûǃQ½☻Ŷ┤▄╪║▒█"
# index -1 is the 'brightest' -> |
ansi_array = img2ansi(input_img, font, sort_glyphs=False, char_set=char_set, ansi_type=ansicolor4Bit, factor=200)
# ansi2img() returns a PIL.Image.Image object
ansi_img = ansi2img(ansi_array, font, font_size=16)
ansi_img.show()
```
### Installation
Install the package using `pip`:
```bash
pip install chromatic-python
```
Raw data
{
"_id": null,
"home_page": null,
"name": "chromatic-python",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "ansi, ascii, art, font, image, terminal, parser",
"author": "crypt0lith",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/d1/5c/137a45895f1ad4628b25169440c8f2a305ddb9d97771e5db764167d02e88/chromatic_python-0.3.2.tar.gz",
"platform": null,
"description": "\r\n\r\n[](https://pypi.org/project/chromatic-python/)\r\n\r\n[](https://pepy.tech/projects/chromatic-python)\r\n[](https://mypy-lang.org/)\r\n\r\nChromatic is a library for processing and transforming ANSI escape sequences (colored terminal text).\r\n\r\nIt offers a collection of algorithms and types for a variety of use cases:\t\r\n- Image-to-ASCII / Image-to-ANSI conversions.\r\n- ANSI art rendering, with support for user-defined fonts.\r\n- A `ColorStr` type which enables precise low-level control over ANSI-escaped strings through a convenient interface.\r\n- [colorama](https://github.com/tartley/colorama/)-style wrappers (`Fore`, `Back`, `Style`).\r\n- Parametrization of ANSI color bit formats, allowing arbitrary conversion between 16-color, 256-color, and true-color (RGB) colorspace on any object implementing a `colorbytes` buffer.\r\n- Et Cetera \ud83d\ude32\r\n\r\n### Usage\r\n#### ColorStr\r\n```python\r\nfrom chromatic import ColorStr\r\n\r\nbase_str = 'hello world'\r\n\r\nred_fg = ColorStr(base_str, 0xFF0000)\r\n\r\nassert red_fg.base_str == base_str\r\nassert red_fg.rgb_dict == {'fg': (0xFF, 0, 0)}\r\nassert red_fg.ansi == b'\\x1b[38;5;196m'\r\n```\r\n\r\n`ColorStr` can handle different signatures for `color_spec`:\r\n```python\r\nfrom chromatic import ColorStr\r\n\r\nassert all(\r\n\tColorStr('*', cs) == ColorStr('*', 0xFF0000)\r\n for cs in [b'\\x1b[38;5;196m', b'\\xff\\x00\\x00', (0xFF, 0, 0), {'fg': 0xFF0000}]\r\n)\r\n```\r\n\r\nThe ANSI color format can be given as an argument, or returned by `ColorStr.as_ansi_type()` as a new instance.\r\n```python\r\nfrom chromatic import ColorStr, ansicolor24Bit, ansicolor4Bit\r\n\r\ntruecolor = ColorStr('*', 0xFF0000, ansi_type=ansicolor24Bit)\r\na_16color = truecolor.as_ansi_type(ansicolor4Bit)\r\n\r\n# each ansi color format has an alias that can be used in place of the type object\r\nassert a_16color == truecolor.as_ansi_type('4b')\r\n\r\nassert truecolor.ansi_format is ansicolor24Bit and truecolor.ansi == b'\\x1b[38;2;255;0;0m'\r\nassert a_16color.ansi_format is ansicolor4Bit and a_16color.ansi == b'\\x1b[31m'\r\n```\r\n\r\nAdding and removing specific ANSI codes from the escape sequence:\r\n```python\r\nimport chromatic as cm\r\n\r\nboring_str = cm.ColorStr('hello world')\r\n\r\nassert boring_str.ansi == b''\r\n\r\nbold_str = boring_str + cm.SgrParameter.BOLD\r\nassert bold_str.ansi == b'\\x1b[1m'\r\n\r\n# use ColorStr.update_sgr() to remove and add SGR values\r\nunbold_str = bold_str.update_sgr(cm.SgrParameter.BOLD)\r\nassert unbold_str == boring_str\r\nassert bold_str == unbold_str.update_sgr(cm.SgrParameter.BOLD)\r\n```\r\n\r\n#### Image-to-ANSI conversion\r\n\r\nConverting an image into an array of ANSI-escaped characters, then rendering the ANSI array as another image:\r\n```python\r\nfrom chromatic.color import ansicolor4Bit\r\nfrom chromatic.ascii import ansi2img, img2ansi\r\nfrom chromatic.data import UserFont, butterfly\r\n\r\ninput_img = butterfly()\r\n\r\nfont = UserFont.IBM_VGA_437_8X16\r\n\r\n# by default, `char_set` would be sorted based on the relative weight of glyphs in the font\r\n# but because `sort_glyphs` is set to False, `char_set` will be directly mapped to the image brightness\r\n# | <- index 0 is the 'darkest'\r\nchar_set = r\"'\u00b7,\u2022-_\u2192+<>\u207f*%\u23027\u221aI\u00ef\u221e\u03c0bz\u00a39y\u00eeU{}1\u03b1HSw\u2665\u00e6?GX\u2555\u2552\u00e9\u00e0\u2321MF\u255d\u2569\u0398\u00fb\u00c7\u0192Q\u00bd\u263b\u00c5\u00b6\u2524\u2584\u256a\u2551\u2592\u2588\"\r\n# index -1 is the 'brightest' -> |\r\n\r\nansi_array = img2ansi(input_img, font, sort_glyphs=False, char_set=char_set, ansi_type=ansicolor4Bit, factor=200)\r\n\r\n# ansi2img() returns a PIL.Image.Image object\r\nansi_img = ansi2img(ansi_array, font, font_size=16)\r\nansi_img.show()\r\n```\r\n\r\n### Installation\r\nInstall the package using `pip`:\r\n```bash\r\npip install chromatic-python\r\n```\r\n",
"bugtrack_url": null,
"license": null,
"summary": "ANSI art image processing and colored terminal text",
"version": "0.3.2",
"project_urls": {
"Homepage": "https://github.com/crypt0lith/chromatic"
},
"split_keywords": [
"ansi",
" ascii",
" art",
" font",
" image",
" terminal",
" parser"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "da33796fb2f2932d4d837d816c82b0d7567e4c2729f06829f66c4148c9eaa3ac",
"md5": "e889b8394c0c20dea01ca09125d77b04",
"sha256": "3ff7990e523b800dd03ad3ee7bfa7ee3eec39ea12a9b3d8f7f1f20050a5b1352"
},
"downloads": -1,
"filename": "chromatic_python-0.3.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e889b8394c0c20dea01ca09125d77b04",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 920907,
"upload_time": "2025-08-05T03:47:42",
"upload_time_iso_8601": "2025-08-05T03:47:42.012127Z",
"url": "https://files.pythonhosted.org/packages/da/33/796fb2f2932d4d837d816c82b0d7567e4c2729f06829f66c4148c9eaa3ac/chromatic_python-0.3.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d15c137a45895f1ad4628b25169440c8f2a305ddb9d97771e5db764167d02e88",
"md5": "45887c948a8bb01d62375c3063f64784",
"sha256": "4a8681c9f544dd7f082a6f859475b6074f19664f2cd52c8dd03725be0ff2eaa0"
},
"downloads": -1,
"filename": "chromatic_python-0.3.2.tar.gz",
"has_sig": false,
"md5_digest": "45887c948a8bb01d62375c3063f64784",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 1055102,
"upload_time": "2025-08-05T03:47:43",
"upload_time_iso_8601": "2025-08-05T03:47:43.885547Z",
"url": "https://files.pythonhosted.org/packages/d1/5c/137a45895f1ad4628b25169440c8f2a305ddb9d97771e5db764167d02e88/chromatic_python-0.3.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-05 03:47:43",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "crypt0lith",
"github_project": "chromatic",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "fonttools",
"specs": [
[
"==",
"4.59.0"
]
]
},
{
"name": "imageio",
"specs": [
[
"==",
"2.37.0"
]
]
},
{
"name": "joblib",
"specs": [
[
"==",
"1.5.1"
]
]
},
{
"name": "lazy-loader",
"specs": [
[
"==",
"0.4"
]
]
},
{
"name": "networkx",
"specs": [
[
"==",
"3.5"
]
]
},
{
"name": "numpy",
"specs": [
[
"==",
"2.2.6"
]
]
},
{
"name": "opencv-python",
"specs": [
[
"==",
"4.12.0.88"
]
]
},
{
"name": "packaging",
"specs": [
[
"==",
"25.0"
]
]
},
{
"name": "pillow",
"specs": [
[
"==",
"11.3.0"
]
]
},
{
"name": "scikit-image",
"specs": [
[
"==",
"0.25.2"
]
]
},
{
"name": "scikit-learn",
"specs": [
[
"==",
"1.7.1"
]
]
},
{
"name": "scipy",
"specs": [
[
"==",
"1.16.1"
]
]
},
{
"name": "threadpoolctl",
"specs": [
[
"==",
"3.6.0"
]
]
},
{
"name": "tifffile",
"specs": [
[
"==",
"2025.6.11"
]
]
}
],
"lcname": "chromatic-python"
}