File: tutorial.rst

package info (click to toggle)
python-term-image 0.7.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,708 kB
  • sloc: python: 8,300; makefile: 75
file content (326 lines) | stat: -rw-r--r-- 9,625 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
Tutorial
========

This is a basic introduction to using the library. Please refer to the :doc:`/api/index` for detailed description of the features and functionality provided by the library.

For this tutorial we'll be using the image below:

.. image:: /resources/tutorial/python.png

The image has a resolution of **288x288 pixels**.

.. note:: All the samples in this tutorial occurred in a terminal window of **255 columns by 70 lines**.


Creating an Instance
--------------------

Image instances can be created using the convenience functions :py:func:`~term_image.image.AutoImage`,
:py:func:`~term_image.image.from_file` and :py:func:`~term_image.image.from_url`,
which automatically detect the best style supported by the terminal emulator.

Instances can also be created using the :ref:`image-classes` directly via their respective
constructors or :py:meth:`~term_image.image.BaseImage.from_file` and
:py:meth:`~term_image.image.BaseImage.from_url` methods.

1. Initialize with a file path:

   ::

      from term_image.image import from_file

      image = from_file("path/to/python.png")

2. Initialize with a URL:
   
   ::

      from term_image.image import from_url

      image = from_url("https://raw.githubusercontent.com/AnonymouX47/term-image/main/docs/source/resources/tutorial/python.png")

3. Initialize with a PIL (Pillow) image instance:

   ::

      from PIL import Image
      from term_image.image import AutoImage

      img = Image.open("path/to/python.png")
      image = AutoImage(img)


Rendering an Image
------------------

Rendering an image is the process of converting it (per-frame for :term:`animated`
images) into text (a string) which reproduces a representation or approximation of
the image when written to the terminal.

.. hint:: To display the rendered image in the following steps, pass the string as an argument to :py:func:`print`.

There are two ways to render an image:

Unformatted Rendering
^^^^^^^^^^^^^^^^^^^^^
This is done using::

   str(image)

The image is rendered without *padding*/*alignment* and with transparency enabled.

The output (using :py:func:`print`) should look like:

.. image:: /resources/tutorial/str.png

|

.. _formatted-render:

Formatted Rendering
^^^^^^^^^^^^^^^^^^^
.. note::
   To see the effect of :term:`alignment` in the steps below, set the image size
   **smaller** than **your** terminal size, with e.g::

     image.height = 50

   This sets the image height to ``50`` lines (which is less than ``70``, the height of
   the terminal window used to prepare this tutorial) and the width proportionally.

   We'll see more about this later.

Below are examples of formatted rendering:

::

   format(image, "|200.^70#ffffff")

Renders the image with:

* **center** :term:`horizontal alignment`
* a :term:`padding width` of **200** columns
* **top** :term:`vertical alignment`
* a :term:`padding height` of **70** lines
* **white** (``#ffffff``) background underlay

.. note::
   You might have to reduce the padding width (200) and/or height (70) to something that'll
   fit into your terminal window, or increase the size of the terminlal window

The output (using :py:func:`print`) should look like:

.. image:: /resources/tutorial/white_bg.png

|

::

   f"{image:>._#.5}"

Renders the image with:

* **right** :term:`horizontal alignment`
* **default** :term:`padding width` (the current :term:`terminal width`)
* **bottom** :term:`vertical alignment`
* **default** :term:`padding height` (the current :term:`terminal height` minus two (``2``))
* transparent background with **0.5** :term:`alpha threshold`

The output (using :py:func:`print`) should look like:

.. image:: /resources/tutorial/alpha_0_5.png

|

::

   "{:1.1#}".format(image)

Renders the image with:

* **center** :term:`horizontal alignment` (default)
* **no** horizontal :term:`padding`, since ``1`` is less than or equal to the image width
* **middle** :term:`vertical alignment` (default)
* **no** vertical :term:`padding`, since ``1`` is less than or equal to the image height
* transparency is **disabled** (alpha channel is ignored)

The output (using :py:func:`print`) should look like:

.. image:: /resources/tutorial/no_alpha_no_align.png

.. seealso:: :doc:`/guide/formatting` and :ref:`format-spec`


Drawing/Displaying an Image
---------------------------

There are two basic ways to draw an image to the terminal screen:

1. Using the :py:meth:`~term_image.image.BaseImage.draw` method::

      image.draw()

   **NOTE:** :py:meth:`~term_image.image.BaseImage.draw` has various parameters for
   :doc:`/guide/formatting`.

2. Using :py:func:`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 :term:`animated` images, only the former animates the output, the latter only
     draws the **current** frame (see :py:meth:`seek() <term_image.image.BaseImage.seek()>`
     and :py:meth:`tell() <term_image.image.BaseImage.tell()>`).
   * Also, the former performs size validation to see if the image will fit into the
     terminal, while the latter doesn't.


.. important:: All the examples **above** use :term:`dynamic <dynamic size>` and
   :term:`automatic <automatic size>` sizing.


Image Size
----------

| The size of an image determines the dimension of its render output.
| The image size can be retrieved via the :py:attr:`~term_image.image.BaseImage.size`,
  :py:attr:`~term_image.image.BaseImage.width` and :py:attr:`~term_image.image.BaseImage.height` properties.

The size of an image can be in either of two states:

1. Fixed

   In this state,
   
   * the ``size`` property evaluates to a 2-tuple of integers, while the ``width`` and
     ``height`` properties evaluate to integers,
   * the image is rendered with the set size.

2. Dynamic

   In this state,

   * the ``size``, ``width`` and ``height`` properties evaluate to a
     :py:class:`~term_image.image.Size` enum member,
   * the size with which the image is rendered is automatically calculated
     (based on the current :term:`terminal size` or the image's original size) whenever the
     image is to be rendered.

The size of an image can be set at instantiation by passing an integer or a
:py:class:`~term_image.image.Size` enum member to **either** the *width* **or** the
*height* **keyword-only** parameter.
For whichever axis a dimension is given, the dimension on the other axis is calculated
**proportionally**.

.. note::
   1. The arguments can only be given **by keyword**.
   2. If neither is given, the :py:attr:`~term_image.image.Size.FIT` :term:`dynamic size`
      applies.
   3. All methods of instantiation accept these arguments.

For example:

>>> from term_image.image import Size, from_file
>>> image = from_file("python.png")  # Dynamic FIT
>>> image.size is Size.FIT
True
>>> image = from_file("python.png", width=60)  # Fixed
>>> image.size
(60, 30)
>>> image.height
30
>>> image = from_file("python.png", height=56)  # Fixed
>>> image.size
(112, 56)
>>> image.width
112
>>> image = from_file("python.png", height=Size.FIT)  # Fixed FIT
>>> image.size
(136, 68)
>>> image = from_file("python.png", width=Size.FIT_TO_WIDTH)  # Fixed FIT_TO_WIDTH
>>> image.size
(255, 128)
>>> image = from_file("python.png", height=Size.ORIGINAL)  # Fixed ORIGINAL
>>> image.size
(288, 144)

No size validation is performed i.e the resulting size might not fit into the terminal window

>>> image = from_file("python.png", height=68)  # Will fit in, OK
>>> image.size
(136, 68)
>>> image = from_file("python.png", height=500)  # Will not fit in, also OK
>>> image.size
(1000, 500)

An exception is raised when both *width* and *height* are given.

>>> image = from_file("python.png", width=100, height=100)
Traceback (most recent call last):
  .
  .
  .
ValueError: Cannot specify both width and height

The :py:attr:`~term_image.image.BaseImage.width` and :py:attr:`~term_image.image.BaseImage.height`
properties can be used to set the size of an image after instantiation, resulting in :term:`fixed size`.

>>> image = from_file("python.png")
>>> image.width = 56
>>> image.size
(56, 28)
>>> image.height
28
>>> image.height = 68
>>> image.size
(136, 68)
>>> image.width
136
>>> # Even though the terminal can't contain the resulting height, the size is still set
>>> image.width = 200
>>> image.size
(200, 100)
>>> image.width = Size.FIT
>>> image.size
(136, 69)
>>> image.height = Size.FIT_TO_WIDTH
>>> image.size
(255, 128)
>>> image.height = Size.ORIGINAL
>>> image.size
(288, 144)

The :py:attr:`~term_image.image.BaseImage.size` property can only be set to a
:py:class:`~term_image.image.Size` enum member, resulting in :term:`dynamic size`.

>>> image = from_file("python.png")
>>> image.size = Size.FIT
>>> image.size is image.width is image.height is Size.FIT
True
>>> image.size = Size.FIT_TO_WIDTH
>>> image.size is image.width is image.height is Size.FIT_TO_WIDTH
True
>>> image.size = Size.ORIGINAL
>>> image.size is image.width is image.height is Size.ORIGINAL
True

.. important::

   1. The currently set :term:`cell ratio` is also taken into consideration when
      calculating sizes for images of :ref:`text-based`.
   2. There is a **2-line** difference between the **default** :term:`frame size` and
      the terminal size to allow for shell prompts and the likes.

.. tip::

   See :py:meth:`~term_image.image.BaseImage.set_size` for extended sizing control.


|

To explore more of the library's features and functionality, check out the
:doc:`/guide/index` and the :doc:`/api/index`.