textual-kitty
Render images directly in your terminal using Textual and Rich.
textual-kitty offers both a Rich renderable and a Textual Widget that leverage the Terminal Graphics Protocol (TGP) protocol to display images in your terminal. For terminals that don't support TGP, fallback rendering using Unicode characters is available.
Supported Terminals
The Terminal Graphics Protocol (TGP) was initially introduced by the Kitty terminal emulator and is completely supported therein. Additionally, TGP is largely implemented in WezTerm and partially supported by Konsole and wayst.
Note: Testing has been conducted primarily using Kitty. Feedback and interoperability testing on other terminal emulators would be highly valued.
Installation
Install textual-kitty using pip with the following commands:
For the basic installation:
pip install textual-kitty
To include the Textual Widget's dependencies:
pip install textual-kitty[textual]
Demonstration
Once installed, run demo application to see the module in action.
For a demonstration of the Rich renderable, use:
python -m textual_kitty rich
For a demonstration of the Textual Widget, use:
python -m textual_kitty textual
The module will automatically select the best available rendering option. If you wish to specify a particular rendering method, use the -p argument with one of the following values: tgp, halfcell, or unicode.
For more information, use:
python -m textual_kitty --help
Usage
Rich Integration
To use the Rich renderable, simply pass an instance of textual_kitty.renderable.Image to a Rich function that renders data:
from rich.console import Console
from textual_kitty.renderable import Image
console = Console()
console.print(Image("path/to/image.png"))
The Image constructor accepts either a string, a pathlib.Path representing the file path of an image readable by Pillow, or a Pillow Image instance directly.
By default, the image is rendered in its original dimensions. You can modify this behavior by specifying the width and/or height parameters. These can be defined as an integer (number of cells), a percentage string (e.g., 50%), or the literal auto to automatically scale while maintaining the aspect ratio.
textual_kitty.renderable.Image defaults to the best available rendering method. To specify a explicit rendering method, use one of the following classes: textual_kitty.renderable.tgp.Image, textual_kitty.renderable.halfcell.Image, or textual_kitty.renderable.unicode.Image.
Textual Integration
For integration with Textual, textual-kitty offers a Textual Widget to render images:
from textual.app import App, ComposeResult
from textual_kitty.widget import Image
class ImageApp(App[None]):
def compose(self) -> ComposeResult:
yield Image("path/to/image.png")
ImageApp().run()
The Image constructor accepts either a string or a pathlib.Path with the file path of an image readable by Pillow, or a Pillow Image instance directly.
You can also set the image using the image property of an Image instance:
from textual.app import App, ComposeResult
from textual_kitty.textual import Image
class ImageApp(App[None]):
def compose(self) -> ComposeResult:
image = Image()
image.image = "path/to/image.png"
yield image
ImageApp().run()
If a different image is set, the Widget will update to display the new image.
By default, the best available rendering option is used. To override this, you can instantiate textual_kitty.widget.TGPImage, textual_kitty.widget.HalfcellImage, or textual_kitty.widget.UnicodeImage directly.
Note: The process of determining the best available rendering option involves querying the terminal, which means sending and receiving data. Since Textual starts threads to handle input and output, this query will not work once the Textual app has started. Therefore, make sure that textual_kitty.renderable is imported before running the Textual app (which is typically the case in most use cases).
Contribution
If you find this module useful, please consider starring the repository on GitHub.
This project began by moving some TGP functionality from a private project to a public GitHub repository and PyPI package, with some additional code added along the way. If you encounter any issues, please file an issue on GitHub.
Contributions via pull requests are welcome and encouraged.
Metadata
Release files for textual-kitty 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| textual_kitty-0.4.0.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| textual_kitty-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.3 kB
Release files / textual_kitty-0.4.0.tar.gz
| Download URL | textual_kitty-0.4.0.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b0892951378f32b85aacf30bf70df05fe8df903bf7b74145cc123f32cda49c34
|
|
BLAKE2b-256 checksum How to use checksums |
af8006c97b21b872cc1d5f9662bc15df4418964bba0aaa05e89db9a73687535a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.1.1 CPython/3.12.6
|
Release files / textual_kitty-0.4.0-py3-none-any.whl
| Download URL | textual_kitty-0.4.0-py3-none-any.whl |
|---|---|
| Size | 11.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc9c07045ad2dcc94f23bf418def26177203fb0e00b1a82882fb55e2a5831157
|
|
BLAKE2b-256 checksum How to use checksums |
68db59eb75ece99f7f3af76964dce7c3607691d5ab1bd965c87d8f2c76b40d5d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.1.1 CPython/3.12.6
|