chromatic-python


Namechromatic-python JSON
Version 0.3.2 PyPI version JSON
download
home_pageNone
SummaryANSI art image processing and colored terminal text
upload_time2025-08-05 03:47:43
maintainerNone
docs_urlNone
authorcrypt0lith
requires_python>=3.12
licenseNone
keywords ansi ascii art font image terminal parser
VCS
bugtrack_url
requirements fonttools imageio joblib lazy-loader networkx numpy opencv-python packaging pillow scikit-image scikit-learn scipy threadpoolctl tifffile
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![image](/logo/logo.PNG)

[![image](https://img.shields.io/pypi/v/chromatic-python)](https://pypi.org/project/chromatic-python/)
![image](https://img.shields.io/pypi/pyversions/chromatic-python)
[![image](https://static.pepy.tech/badge/chromatic-python)](https://pepy.tech/projects/chromatic-python)
[![image](https://mypy-lang.org/static/mypy_badge.svg)](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": "![image](/logo/logo.PNG)\r\n\r\n[![image](https://img.shields.io/pypi/v/chromatic-python)](https://pypi.org/project/chromatic-python/)\r\n![image](https://img.shields.io/pypi/pyversions/chromatic-python)\r\n[![image](https://static.pepy.tech/badge/chromatic-python)](https://pepy.tech/projects/chromatic-python)\r\n[![image](https://mypy-lang.org/static/mypy_badge.svg)](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"
}
        
Elapsed time: 0.76417s