Tutorial
This is a basic introduction to using the library. Please refer to the Reference for detailed description of the features and functionality provided by the library.
For this tutorial we’ll be using the image below:
The image has a resolution of 288x288 pixels.
Note
All the samples in this tutorial occured in a terminal of 255 columns by 70 lines.
Creating an instance
If the file is stored on your local filesystem:
from term_img.image import TermImage
image = TermImage.from_file("python.png")
You can also use a URL if you don’t have the file stored locally:
from term_img.image import TermImage
image = TermImage.from_url("https://raw.githubusercontent.com/AnonymouX47/term-img/docs/source/resources/python.png")
The library can also be used with PIL images:
from PIL import Image
from term_img.image import TermImage
img = Image.open("python.png")
image = TermImage(img)
Rendering an image
Rendering an image is simply the process of converting it (per-frame for animated images) into text (a string).
Hint
To display the rendered output in the following steps, just print the output string with print()
.
There are two ways to render an image:
1. Unformatted
str(image)
Renders the image without padding/alignment and with transparency enabled
The result should look like:
2. Formatted
Note
To see the effect of alignment in the steps below, please scale the image down using:
image.scale = 0.75
This simply sets the x-axis and y-axis scales of the image to 0.75
. We’ll see more about this later.
Below are examples of formatted rendering:
format(image, "|200.^70#ffffff")
Renders the image with:
center horizontal alignment
a padding width of 200 columns
a padding height of 70 lines
transparent background replaced with a white (
#ffffff
) background
Note
If you get an error while trying the step above, saying something like “padding width larger than…”, either:
reduce the width (200) to something that’ll fit into your terminal window, or
increase the size of the terminlal window
You might use your own terminal height instead of 70.
The result should look like:
f"{image:>._#.5}"
Renders the image with:
right horizontal alignment
automatic padding width (the current terminal width minus horizontal allowance)
bottom vertical alignment
automatic padding height (the current terminal height minus vertical allowance)
transparent background with 0.5 alpha threshold
The result should look like:
"{:1.1#}".format(image)
Renders the image with:
center horizontal alignment (default)
no horizontal padding, since
1
must be less than or equal to the image widthmiddle vertical alignment (default)
no vertical padding, since
1
is less than or equal to the image heighttransparency disabled (black background)
The result should look like:
You should also have a look at the complete Image Format Specification.
Drawing/Displaying an image to/in the terminal
There are two ways to draw an image to the terminal screen:
The
draw()
methodimage.draw()
NOTE:
TermImage.draw()
has various parameters for alignment/padding, transparency and animation control.Using
print()
with an image render output (i.e printing the rendered string)print(image) # Uses str()
OR
print(f"{image:>200.^70#ffffff}") # Uses format()
Note
For animated images, only the first method animates the output, the second only draws the current frame (see TermImage.seek()
and TermImage.tell()
).
Image render size
The render size of an image can be in either of two states:
Set
The size is said the be set when the image has a fixed size.In this state, thesize
property is atuple
of integers, thewidth
andheight
properties are integers.
Unset
The size is said to be unset when the image doesn’t have a fixed size.In this case, the size with which the image is rendered is automatically calculated (based on the current term:`terminal size) whenever the image is to be rendered.In this state, thesize
,width
andheight
properties areNone
.
Note
The arguments can only be given by keyword.
If neither is given, the size is unset.
All methods of instantiation accept these arguments.
For example:
>>> image = Termimage.from_file("python.png") # Unset
>>> image.size is None
True
>>> image = TermImage.from_file("python.png", width=60) # width is given
>>> image.size
(60, 60)
>>> image.height
60
>>> image = TermImage.from_file("python.png", height=56) # height is given
>>> image.size
(56, 56)
>>> image.width
56
The resulting size must fit into the terminal window
>>> image = TermImage.from_file("python.png", height=136) # (terminal_height - 2) * 2; Still OK
>>> image.size
(136, 136)
>>> image = TermImage.from_file("python.png", height=137) # Not OK
Traceback (most recent call last):
.
.
.
term_img.exceptions.InvalidSize: The resulting rendered size will not fit into the available size
An exception is raised when both width and height are given.
>>> image = TermImage.from_file("python.png", width=100, height=100)
Traceback (most recent call last):
.
.
.
ValueError: Cannot specify both width and height
The width
and height
properties are used to set the render size of an image after instantiation.
>>> image = Termimage.from_file("python.png") # Unset
>>> image.size is None
True
>>> image.width = 56
>>> image.size
(56, 56)
>>> image.height
56
>>> image.height = 136
>>> image.size
(136, 136)
>>> image.width
136
>>> image.width = 200 # Even though the terminal can contain this width, it can't contain the resulting height
Traceback (most recent call last):
.
.
.
term_img.exceptions.InvalidSize: The resulting rendered size will not fit into the available size
Setting width
or height
to None
sets the size to that automatically calculated based on the current terminal size.
>>> image = Termimage.from_file("python.png") # Unset
>>> image.size is None
True
>>> image.width = None
>>> image.size
(136, 136)
>>> image.width = 56
>>> image.size
(56, 56)
>>> image.height = None
>>> image.size
(136, 136)
The size
property can only be set to one value, None
and doing this unsets the render size.
>>> image = Termimage.from_file("python.png", width=100)
>>> image.size
(100, 100)
>>> image.size = None
>>> image.size is image.width is image.height is None
True
Important
The currently set font ratio is also taken into consideration when calculating or validating sizes.
By default, the resulting size must not exceed the terminal size i.e for both the given axis and the axis automatically calculated.
The height is actually about twice the number of lines that’ll be used to draw the image, assuming the y-axis scale is
1.0
(we’ll get to that).There is a default 2-line vertical allowance, to allow for shell prompts or the likes.
Therefore, by default, only terminal_height - 2
lines are available i.e the maximum height is (terminal_height - 2) * 2
.
Hint
See TermImage.set_size()
for advanced sizing control.
Image render scale
float
in the range 0 < x <= 1
i.e greater than zero and less than or equal to one.The render scale can be retrieved via the properties scale
, scale_x
and scale_y
.
The scale can be set at instantiation by passing a value to the scale keyword-only paramter.
>>> image = Termimage.from_file("python.png", scale=(0.75, 0.6))
>>> image.scale
>>> (0.75, 0.6)
The rendered result (using image.draw()
) should look like:
If the scale argument is ommited, the default scale (1.0, 1.0)
is used.
>>> image = Termimage.from_file("python.png")
>>> image.scale
>>> (1.0, 1.0)
The rendered result (using image.draw()
) should look like:
scale
accepts a tuple of two scale values or a single scale value.scale_x
and scale_y
each accept a single scale value.>>> image = Termimage.from_file("python.png")
>>> image.scale = (.3, .56756)
>>> image.scale
(0.3, 0.56756)
>>> image.scale = .5
>>> image.scale
(0.5, 0.5)
>>> image.scale_x = .75
>>> image.scale
(0.75, 0.5)
>>> image.scale_y = 1.
>>> image.scale
(0.75, 1.0)
Finally, to explore more of the library’s features and functionality, check out the Reference section.