File: quickstart.rst

package info (click to toggle)
colorzero 2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 460 kB
  • sloc: python: 2,565; makefile: 264
file content (219 lines) | stat: -rw-r--r-- 6,924 bytes parent folder | download | duplicates (2)
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
.. The colorzero color library
..
.. Copyright (c) 2016-2021 Dave Jones <dave@waveform.org.uk>
..
.. SPDX-License-Identifier: BSD-3-Clause

===============
Getting started
===============

.. currentmodule:: colorzero

The :class:`Color` class is the main interface provided by colorzero. It can be
constructed in a large variety of ways including with red, green, and blue
components, "well known" color names (taken from CSS 3's `extended color
keywords`_), HTML color specifications, and more. A selection of valid
constructors is shown below:

.. code-block:: pycon

    >>> from colorzero import *
    >>> Color('red')
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>
    >>> Color(1.0, 0.0, 0.0)
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>
    >>> Color(255, 0, 0)
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>
    >>> Color('#ff0000')
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>
    >>> Color('#f00')
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>

Internally, colorzero always represents colors as red, green, and blue values
between 0.0 and 1.0. :class:`Color` objects are tuple descendents. Crucially,
this means they are *immutable*. Attempting to change the red, green, or blue
attributes will fail:

.. code-block:: pycon

    >>> c = Color('red')
    >>> c.red
    Red(1.0)
    >>> c.red = 0.5
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: can't set attribute

In order to manipulate a color, colorzero provides a simple series of classes
which represent attributes of a color: :class:`Red`, :class:`Green`,
:class:`Blue`, :class:`Hue`, :class:`Lightness`, :class:`Saturation` and so on.
You can use these classes in combination with Python's usual mathematical
operators (addition, subtraction, multiplication, etc.) to manipulate a color.
For example, continuing the example from above:

.. code-block:: pycon

    >>> c + Green(0.1)
    <Color html='#ff1a00' rgb=(1, 0.1, 0)>
    >>> c = c + Green(0.5)
    >>> c
    <Color html='#ff8000' rgb=(1, 0.5, 0)>
    >>> c.lightness
    Lightness(0.5)
    >>> c = c * Lightness(0.5)
    >>> c
    <Color html='#804000' rgb=(0.5, 0.25, 0)>

Numerous attributes are provided to enable conversion of the RGB representation
to other systems:

.. code-block:: pycon

    >>> c.rgb
    RGB(r=0.5, g=0.25, b=0.0)
    >>> c.rgb_bytes
    RGB(r=128, g=64, b=0)
    >>> c.rgb565
    31200
    >>> c.hls
    HLS(h=0.08333333333333333, l=0.25, s=1.0)
    >>> c.xyz
    XYZ(x=0.10647471144683732, y=0.0819048964489466, z=0.010202272707313633)
    >>> c.lab
    Lab(l=34.376494620040376, a=23.890819210881016, b=44.69197916172735)

Equivalent constructors exist for all these systems:

.. code-block:: pycon

    >>> Color.from_rgb(0.5, 0.25, 0.0)
    <Color html='#804000' rgb=(0.5, 0.25, 0)>
    >>> Color.from_rgb_bytes(128, 64, 0)
    <Color html='#804000' rgb=(0.501961, 0.25098, 0)>
    >>> Color.from_rgb565(31200)
    <Color html='#7b3d00' rgb=(0.483871, 0.238095, 0)>
    >>> Color.from_hls(*c.hls)
    <Color html='#804000' rgb=(0.5, 0.25, 0)>
    >>> Color.from_xyz(*c.xyz)
    <Color html='#7f4000' rgb=(0.5, 0.25, 0)>
    >>> Color.from_lab(*c.lab)
    <Color html='#7f4000' rgb=(0.5, 0.25, 0)>

Note that some conversions lose a certain amount of precision.

The :func:`repr` output of :class:`Color` is relatively verbose by default, but
this can be customized via the :class:`Color.repr_style` class attribute:

.. code-block:: pycon

    >>> c = Color('red')
    >>> c
    <Color html="#ff0000" rgb=(1.0, 0.0, 0.0)>
    >>> Color.repr_style = 'html'
    >>> c
    Color('#ff0000')
    >>> Color.repr_style = 'rgb'
    >>> c
    Color(1, 0, 0)

If you have a terminal capable of color output (usually this means an actual
terminal, not those integrated into applications like IDLE, Thonny, etc.), you
can also preview colors with this facility (the output below shows the ANSI
codes produced, but the documentation system won't reproduce the colored
output):

.. code-block:: pycon

    >>> Color.repr_style = 'term256'
    >>> c
    <Color ### rgb=(1, 0, 0)>
    >>> repr(c)
    '<Color \x1b[38;5;9m###\x1b[0m rgb=(1, 0, 0)>'
    >>> Color.repr_style = 'term16m'
    >>> c
    <Color ### rgb=(1, 0, 0)>
    >>> repr(c)
    '<Color \x1b[38;2;255;0;0m###\x1b[0m rgb=(1, 0, 0)>'

These ANSI codes can also be generated by using colors with :meth:`str.format`.
For example:

.. code-block:: pycon

    >>> '{c:16m}Red{c:0} Alert!'.format(c=Color('red'))
    '\x1b[38;2;255;0;0mRed\x1b[0m Alert!'

See :ref:`format` for more information.

A method (:meth:`~Color.gradient`) is provided to generate gradients which fade
from one color to another. The result is a generator, which must be iterated
over if you want all the results:

.. code-block:: pycon

    >>> Color.repr_style = 'term16m'
    >>> for c in Color('red').gradient(Color('green')):
    ...     print(repr(c))
    ...
    <Color ### rgb=(1, 0, 0)>
    <Color ### rgb=(0.888889, 0.0557734, 0)>
    <Color ### rgb=(0.777778, 0.111547, 0)>
    <Color ### rgb=(0.666667, 0.16732, 0)>
    <Color ### rgb=(0.555556, 0.223094, 0)>
    <Color ### rgb=(0.444444, 0.278867, 0)>
    <Color ### rgb=(0.333333, 0.334641, 0)>
    <Color ### rgb=(0.222222, 0.390414, 0)>
    <Color ### rgb=(0.111111, 0.446187, 0)>
    <Color ### rgb=(0, 0.501961, 0)>

In a color-capable terminal, the "###" above will appear to fade between the
two specified colors.

Methods are also provided to compare colors for similarity. The simplest
algorithm (and the default) is "euclid" which calculates the difference as the
distance between them by treating the r, g, b components as coordinates in a
3-dimensional space. The same color will have a distance of 0.0, whilst the
largest possible difference is :math:`\sqrt{3}` (:math:`\approx 1.732`):

.. code-block:: pycon

    >>> c1 = Color('red')
    >>> c2 = Color('green')
    >>> c3 = c1 * Lightness(0.9)
    >>> c1.difference(c2, 'euclid')
    1.1189122525867927
    >>> c1.difference(c2)
    1.1189122525867927
    >>> c1.difference(c3)
    0.09999999999999998

Various `Delta-E`_ algorithms (CIE1976, CIE1994, and CIEDE2000) are also
provided. In these systems, 2.3 is considered a "just noticeable difference":

.. code-block:: pycon

    >>> c1.difference(c2, 'cie1976')
    133.10729836196307
    >>> c1.difference(c3, 'cie1976')
    9.60280542204272
    >>> c1.difference(c2, 'cie1994g')
    50.97596644678241
    >>> c1.difference(c3, 'cie1994g')
    5.484832836355026
    >>> c1.difference(c2, 'ciede2000')
    72.18229138962074
    >>> c1.difference(c3, 'ciede2000')
    5.490813507834904

These algorithms are also available as straight-forward functions:

.. code-block:: pycon

    >>> cie1976(c1, c2)
    133.10729836196307
    >>> ciede2000(c1, c3)
    5.490813507834904

.. _extended color keywords: https://www.w3.org/TR/css3-color/#svg-color
.. _Delta-E: https://en.wikipedia.org/wiki/Color_difference